#232 Implement Queue using Stacks
the problem
In plain words
Build a FIFO queue (push, pop, peek, empty) using only standard stack operations: push to top, peek/pop from top, size and isEmpty.
in push(1), push(2), peek(), pop(), empty()
out 1, 1, false
1 went in first, so it comes out first.
- 1 ≤ x ≤ 9
- At most 100 calls
- pop and peek are always valid
- Follow-up: amortized O(1) per operation
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
Design: implement every operation. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternStack & queue design
Pouring one stack into another reverses it — and reversing LIFO gives FIFO. Only pour when the output stack is empty, so each element is poured once.
solutions
From brute force to optimal
Keep the oldest element on top of one stack at all times by moving everything out and back on each push.
- Move all of
mainintotemp. - Push x onto the empty
main(it sits at the bottom = rear). - Move everything back on top of it.
- pop/peek simply read
main's top.
Each push moves all n elements twice.
The two stacks hold the n elements.
// On LeetCode, name this class MyQueue.class MyQueueCostlyPush { private final Deque<Integer> main = new ArrayDeque<>(); // top = front of the queue private final Deque<Integer> temp = new ArrayDeque<>(); public void push(int x) { while (!main.isEmpty()) temp.push(main.pop()); // empty main main.push(x); // x sits at the bottom = rear while (!temp.isEmpty()) main.push(temp.pop()); // older ones go back on top } public int pop() { return main.pop(); } public int peek() { return main.peek(); } public boolean empty() { return main.isEmpty(); }}Push into in. Serve from out. Refill out from in only when out is empty.
- push:
in.push(x). - peek/pop: if
outis empty, pour all ofinintoout. - Return / pop
out's top. - empty: both stacks empty.
Every element is pushed to in once, moved to out once and popped once — a constant amount of work per element.
Each element lives in exactly one of the two stacks.
class MyQueue { private final Deque<Integer> in = new ArrayDeque<>(); // receives every push private final Deque<Integer> out = new ArrayDeque<>(); // serves pops, oldest on top public void push(int x) { in.push(x); } public int pop() { peek(); // makes sure the front is on top of out return out.pop(); } public int peek() { if (out.isEmpty()) { // only refill when out has nothing left while (!in.isEmpty()) out.push(in.pop()); // reversing puts the oldest on top } return out.peek(); } public boolean empty() { return in.isEmpty() && out.isEmpty(); }}Dry run
in the room
How to say it in the interview
talk track
- Say: "Reversing a stack once turns LIFO into FIFO."
- Explain why you must NOT pour while
outstill has elements — that would put newer elements above older ones. - State the complexity carefully: worst case O(n) for one pop, amortized O(1) per operation.
traps
- Pouring
ininto a non-emptyout— breaks the order. - Forgetting that
empty()must check both stacks.
what they ask next
Follow-ups
Can you make every single operation O(1) worst case?
Not with this simple scheme; amortized is what the problem asks for. Real-time queues from stacks exist (incremental transfer) but are rarely expected.
Why does this matter in practice?
It's how purely functional languages build immutable queues (two lists), and the idea behind amortized analysis in general.
before you submit
Edge cases to test
- Push after a transfer: the new element must wait behind everything already in
out— never pour into a non-emptyout. - peek twice in a row returns the same element and removes nothing.
- The queue empties completely and is refilled —
empty()must look at both stacks.
practise next
Similar problems
- #225Implement Stack using QueuesEasyin Queues
- #155Min StackMediumin Stacks
- #622Design Circular QueueMediumin Queues