Deque Fundamentals
Deque Fundamentals
A deque (double-ended queue) allows insertion and removal from both ends.
Core Operations
| Operation | Description | Time |
|---|---|---|
| addFirst | Add to front | O(1) |
| addLast | Add to rear | O(1) |
| removeFirst | Remove from front | O(1) |
| removeLast | Remove from rear | O(1) |
| peekFirst | View front | O(1) |
| peekLast | View rear | O(1) |
Deque as Stack or Queue
// Deque as Stack
deque.push(1); // or addFirst
deque.pop(); // or removeFirst
deque.peek(); // peekFirst
// Deque as Queue
deque.offer(1); // or addLast
deque.poll(); // or removeFirst
deque.peek(); // peekFirst
ArrayDeque Implementation
Deque<Integer> deque = new ArrayDeque<>();
deque.addFirst(1); // [1]
deque.addLast(2); // [1, 2]
deque.addFirst(0); // [0, 1, 2]
int front = deque.removeFirst(); // 0
int back = deque.removeLast(); // 2
When to Use Deque
- Sliding window maximum
- Implementing both stack and queue
- Palindrome checking
- BFS with bidirectional traversal
- Rolling hash computations
Deque Applications
Deque Applications
1. Sliding Window Maximum (LeetCode 239)
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new ArrayDeque<>();
int[] result = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.pollFirst();
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offerLast(i);
if (i >= k - 1) {
result[i - k + 1] = nums[deque.peekFirst()];
}
}
return result;
}
// Time: O(n), Space: O(k)
2. Palindrome Check
public boolean isPalindrome(String s) {
Deque<Character> deque = new ArrayDeque<>();
for (char c : s.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
deque.addLast(Character.toLowerCase(c));
}
}
while (deque.size() > 1) {
if (deque.pollFirst() != deque.pollLast()) {
return false;
}
}
return true;
}
3. Moving Average (LeetCode 346)
class MovingAverage {
Deque<Integer> deque;
int size;
double sum;
public MovingAverage(int size) {
this.deque = new ArrayDeque<>();
this.size = size;
this.sum = 0;
}
public double next(int val) {
deque.offerLast(val);
sum += val;
if (deque.size() > size) {
sum -= deque.pollFirst();
}
return sum / deque.size();
}
}
Deque vs Stack vs Queue
| Feature | Stack | Queue | Deque |
|---|---|---|---|
| Add | Push (top) | Offer (rear) | Both ends |
| Remove | Pop (top) | Poll (front) | Both ends |
| Use | DFS, undo | BFS | Sliding window |
Practice Problems
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. Return the max sliding window.
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Window positions: [1,3,-1]→3, [3,-1,-3]→3, [-1,-3,5]→5, [-3,5,3]→5, [5,3,6]→6, [3,6,7]→7.
Edge Cases:
- k=1: return the array itself
- k=n: return single max of entire array
- All elements equal: return all same values
The median is the middle value in an ordered integer list. Return the median of each sliding window of size k.
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [1.00000,-1.00000,-1.00000,3.00000,5.00000,6.00000]
Median of each window of size 3.
Edge Cases:
- k=1: return nums as doubles
- k=n: return single median of entire array
- All elements same: return that element for all windows
Return any permutation of deck such that when you reveal cards in order (reveal top, move next to bottom), they are revealed in increasing order.
Example:
Input: deck = [17,13,11,2,3,5,7]
Output: [2,13,3,11,5,17,7]
Simulation yields increasing order.
Edge Cases:
- Single card: return that card
- Two cards: reveal first, move second to front, reveal second
- Already sorted: deck order may differ from sorted order
Quiz
1. What operations does a deque support?
2. Can a deque be used as a stack?
3. What is a common mistake when implementing Deque?
Flashcards
Question
What is a deque?
Click to reveal answer
Answer
Double-ended queue allowing insertion/removal from both ends in O(1).
Question
When to use deque over queue?
Click to reveal answer
Answer
When you need to access both ends, or for sliding window problems.
Question
Deque best practices
Click to reveal answer
Answer
Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.
Revision Notes
Key Takeaways
- 1. Deque is more flexible than queue/stack
- 2. O(1) for all end operations
- 3. Use ArrayDeque in Java
- 4. Store indices for sliding window
Interview Tips
- • Explain why deque is needed
- • Discuss ArrayDeque vs LinkedList
- • Mention circular buffer implementation
Cheat Sheet
Deque Cheat Sheet
Operations: addFirst, addLast, removeFirst, removeLast - all O(1)
Use Cases: Sliding window, palindrome, implementing stack/queue
Java: Use ArrayDeque (preferred over LinkedList)
Pattern: Store indices for sliding window problems