Double Ended Queue Deque in DSA Java - Time & Space Complexity
We want to understand how fast operations on a double ended queue (deque) run as the number of items grows.
Specifically, we ask: how does the time to add or remove items from either end change with size?
Analyze the time complexity of the following code snippet.
public class SimpleDeque {
private int[] data = new int[1000];
private int front = 0, rear = 0;
public void addFront(int val) {
front = (front - 1 + data.length) % data.length;
data[front] = val;
}
public void addRear(int val) {
data[rear] = val;
rear = (rear + 1) % data.length;
}
public int removeFront() {
int val = data[front];
front = (front + 1) % data.length;
return val;
}
public int removeRear() {
rear = (rear - 1 + data.length) % data.length;
return data[rear];
}
}
This code shows adding and removing items from both ends of a fixed-size deque using a circular array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Single-step index updates and array assignments or retrievals.
- How many times: Each add or remove operation runs once per call, no loops inside.
Each operation does a fixed number of steps regardless of how many items are in the deque.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5 steps |
| 100 | 5 steps |
| 1000 | 5 steps |
Pattern observation: The time stays the same no matter how many items are stored.
Time Complexity: O(1)
This means adding or removing from either end takes the same short time no matter the deque size.
[X] Wrong: "Removing from the rear takes longer because you have to move all items."
[OK] Correct: The code uses index math to jump directly to the rear item, so no moving of other items happens.
Knowing that deque operations run in constant time shows you understand efficient data structures, a key skill in coding interviews.
"What if the deque used a linked list instead of an array? How would the time complexity of add and remove operations change?"
Practice
Solution
Step 1: Understand the definition of Deque
A Deque allows insertion and deletion from both front and rear ends.Step 2: Compare with other data structures
Unlike queues or stacks, Deque supports operations at both ends.Final Answer:
A data structure where elements can be added or removed from both ends -> Option BQuick Check:
Deque = double-ended queue [OK]
- Confusing Deque with stack or simple queue
- Thinking Deque allows random access like arrays
- Assuming Deque only works from one end
Solution
Step 1: Identify valid Deque implementations in Java
ArrayDeque implements the Deque interface and is the preferred implementation.Step 2: Check syntax correctness
ArrayDeque is instantiated with new ArrayDeque<>(), which is correct syntax.Final Answer:
Deque<Integer> dq = new ArrayDeque<>(); -> Option AQuick Check:
ArrayDeque is standard Deque implementation [OK]
- Using Stack which is not a Deque
- Trying to instantiate interface Queue directly
- Trying to instantiate the Deque interface directly
Deque<String> dq = new ArrayDeque<>();
dq.addFirst("A");
dq.addLast("B");
dq.addFirst("C");
System.out.println(dq);Solution
Step 1: Trace addFirst and addLast operations
addFirst("A") adds A at front: [A]
addLast("B") adds B at rear: [A, B]
addFirst("C") adds C at front: [C, A, B]Step 2: Print the Deque
Printing dq shows elements in order: [C, A, B]Final Answer:
[C, A, B] -> Option CQuick Check:
addFirst adds front, addLast adds rear [OK]
- Mixing order of addFirst and addLast
- Assuming addFirst adds at rear
- Confusing print output format
Deque<Integer> dq = new ArrayDeque<>(); dq.addFirst(10); dq.addLast(20); dq.removeLast(); dq.removeFirst(); dq.removeFirst();
Solution
Step 1: Trace the Deque operations
Start: empty
addFirst(10): [10]
addLast(20): [10, 20]
removeLast(): removes 20 -> [10]
removeFirst(): removes 10 -> []
removeFirst(): tries to remove from empty DequeStep 2: Identify exception on removing from empty Deque
removeFirst() on empty Deque throws NoSuchElementExceptionFinal Answer:
Throws NoSuchElementException on last removeFirst() -> Option DQuick Check:
Removing from empty Deque throws NoSuchElementException [OK]
- Assuming removeFirst returns null instead of exception
- Confusing method names causing compile error
- Thinking removeLast throws NullPointerException
Solution
Step 1: Understand task order requirements
Normal tasks should be processed in arrival order (queue behavior). Urgent tasks should be processed before normal tasks (front insertion).Step 2: Match Deque operations to requirements
addLast() adds normal tasks at rear (end), preserving arrival order.
addFirst() adds urgent tasks at front, prioritizing them.Final Answer:
Use addLast() for normal tasks and addFirst() for urgent tasks -> Option AQuick Check:
Normal at rear, urgent at front [OK]
- Reversing addFirst and addLast roles
- Using only one end for all tasks losing priority
- Confusing queue and stack behavior
Ready to prove it?
Pass the test and this pattern moves unknown
