Design Front Middle Back Queue
Design Front Middle Back Queue is a medium design data structures problem solved with the linked lists pattern.
The best approach, optimal (two balanced deques), runs in O(1) per operation time and O(n) space.
Below are 2 approaches in Java, from one list up.
Problem
Design a queue that supports push and pop at the front, the middle and the back. When there are two middle positions, use the one closer to the front.
Examples
Example 1
- Input
pushFront(1); pushBack(2); pushMiddle(3); pushMiddle(4); popFront(); popMiddle(); popMiddle(); popBack(); popFront()- Output
1, 3, 4, 2, -1- Why
- After the pushes the queue is [1, 4, 3, 2].
Constraints
- Up to 1000 calls; pops on an empty queue return -1.
- With two middles, pushMiddle goes to the front one and popMiddle takes the front one.
Animated walkthrough
A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.
Concepts first, then the problem and every approach, step by step.
Space to play or pause · ← → to jump a step · click or drag the bar to seek
Solutions
Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.
| Approach | Time | Space |
|---|---|---|
| One list | O(n) per operation | O(n) |
| Optimal (two balanced deques) | O(1) per operation | O(n) |
1One list
O(n) per operationO(n)Use a single ArrayList and insert or remove at index 0, size / 2 or the end.
- pushMiddle at size / 2; popMiddle at (size - 1) / 2.
class FrontMiddleBackQueue {
private final List<Integer> a = new ArrayList<>();
public void pushFront(int val) { a.add(0, val); }
public void pushMiddle(int val) { a.add(a.size() / 2, val); }
public void pushBack(int val) { a.add(val); }
public int popFront() { return a.isEmpty() ? -1 : a.remove(0); }
public int popMiddle() { return a.isEmpty() ? -1 : a.remove((a.size() - 1) / 2); }
public int popBack() { return a.isEmpty() ? -1 : a.remove(a.size() - 1); }
}2Optimal (two balanced deques)
O(1) per operationO(n)left holds the front half, right holds the back half, with right.size() == left.size() or left.size() + 1. After every operation, rebalance by moving one element across the boundary. The middle (the front one of two middles) is then left's last element when the sizes are equal, otherwise right's first.
- balance(): if left.size() > right.size(), move left.last to right.first; if right.size() > left.size() + 1, move right.first to left.last.
- pushMiddle: if the halves are equal in size, the new value becomes right's first; otherwise it becomes left's last.
- popMiddle: equal sizes → left's last; otherwise right's first.
class FrontMiddleBackQueue {
private final Deque<Integer> left = new ArrayDeque<>(), right = new ArrayDeque<>();
// invariant: right.size() == left.size() or left.size() + 1
private void balance() {
if (left.size() > right.size()) right.addFirst(left.pollLast());
else if (right.size() > left.size() + 1) left.addLast(right.pollFirst());
}
public void pushFront(int val) { left.addFirst(val); balance(); }
public void pushMiddle(int val) {
if (left.size() == right.size()) right.addFirst(val);
else left.addLast(val);
}
public void pushBack(int val) { right.addLast(val); balance(); }
public int popFront() {
if (right.isEmpty()) return -1;
int v = left.isEmpty() ? right.pollFirst() : left.pollFirst();
balance();
return v;
}
public int popMiddle() {
if (right.isEmpty()) return -1;
int v = left.size() == right.size() ? left.pollLast() : right.pollFirst();
balance();
return v;
}
public int popBack() {
if (right.isEmpty()) return -1;
int v = right.pollLast();
balance();
return v;
}
}Edge cases to test
- popMiddle on an even-length queue
- Operations on an empty queue
Hints
Hint 1
Split the queue into two deques, left and right, keeping left.size() equal to right.size() or one less. The middle is then always at the boundary.
FAQ
What is the best time complexity for Design Front Middle Back Queue?
Optimal (two balanced deques) runs in O(1) per operation time and O(n) extra space.
Which pattern does Design Front Middle Back Queue use?
It is a design data structures problem that uses the linked lists pattern. Other problems with the same pattern: Design Linked List.
Is there a brute force solution for Design Front Middle Back Queue?
Yes. One list takes O(n) per operation time and O(n) space. Use a single ArrayList and insert or remove at index 0, size / 2 or the end.
Which edge cases should I test for Design Front Middle Back Queue?
popMiddle on an even-length queue; Operations on an empty queue.