intermediate8 min read·Updated September 21, 2026
Queue via Two Stacks Explained: Tracing Enqueue 1,2,3 & Dequeue
Master implementing a FIFO queue with two LIFO stacks. Follow our step-by-step walkthrough of enqueue 1,2,3 and dequeue sequences with mental models.
By Learnisim AI·Published September 21, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
- Basic stack operations (push, pop, peek)
- FIFO (First-In, First-Out) queue semantics
- LIFO (Last-In, First-Out) stack semantics
Why
Why Build a FIFO Queue Using Only LIFO Stacks
Phase 1: The LIFO Order Problem
Imagine you are building a data processor where items must be handled strictly in a First-In, First-Out (FIFO) order: the first item that arrives must be the first one processed. However, your programming environment or memory constraints only give you access to a standard Stack data structure. A stack is strictly Last-In, First-Out (LIFO), meaning elements can only be pushed and popped from the top.
Consider our locked working example: you need to enqueue 1, 2, 3; dequeue; enqueue 4; dequeue, dequeue, dequeue. If you try to store incoming elements directly in a single stack, pushing
1, 2, and then 3 leaves 3 sitting right at the top. The moment you call pop, you get 3 instead of the expected 1. That violates the core rule of our queue, which must yield 1 first.Without a clever design, you would have to shift elements around in memory constantly or abandon the stack restriction entirely. We need a way to combine two separate stacks—let's call them
in and out—to reverse that LIFO order into a reliable FIFO queue. We are given this exact sequence of operations, and our challenge is to design a system where these exact enqueues and dequeues execute in correct chronological sequence.Model
The Two-Stack Queue Model: Reversing Order Without Losing FIFO
Phase 2: The Two-Stack Architecture
To bridge the gap between Last-In-First-Out (LIFO) stacks and a First-In-First-Out (FIFO) queue, we divide our data flow into two distinct buckets: an in stack and an out stack. When we perform an enqueue 1,2,3 operation, elements land in the in stack in arrival order, but sitting upside down relative to what a queue needs. To extract them in correct FIFO order, we cannot just pop from the in stack directly—that would yield 3 first, violating our queue contract.
Instead, we treat the in stack purely as a write-append zone and the out stack as a read-drain zone. When a dequeue arrives and the out stack is empty, we pour the entire contents of the in stack into the out stack in a single bulk transfer. This physical inversion flips the order: the bottom of the in stack (which holds our earliest arrival, 1) lands at the very top of the out stack, ready to pop instantly.
Following our locked example, after we enqueue and 3, our in stack holds with 3 at the top. The first dequeue forces a pour into the out stack, reversing into from bottom to top, allowing us to cleanly pop 1 as our first output.
Try this: State the contents of both the in stack and the out stack immediately after the first dequeue operation in the sequence: enqueue 1,2,3; dequeue.
Worked example
Tracing the Locked Example: Enqueue 1, 2, 3 and Dequeue Sequences
Phase 3: Worked Example
Let us trace our locked example end-to-end to watch how the input stack () and output stack () coordinate to preserve strict FIFO order.
Given / Setup:
We start with two empty stacks: and . We will execute the exact sequence: , followed by , then , and finally three consecutive operations.
We start with two empty stacks: and . We will execute the exact sequence: , followed by , then , and finally three consecutive operations.
Steps:
1. :
- Push each item onto the stack as it arrives.
- State: , .
2. (First Dequeue):
- Check the stack. It is empty.
- Transfer all elements from to by popping from and pushing to .
- Popping 3, then 2, then 1 from and pushing them to results in (with 1 at the top).
- Pop the top of (1).
- State: , .
3. :
- Push 4 directly onto the stack (do not touch ).- State: , .
4. (Second Dequeue):
- Check the stack. It is not empty ( with 2 at the top).
- Pop the top of (2) directly without touching .
- State: , .
5. (Third Dequeue):
- Pop the next item from (3).
- State: , .
6. (Fourth Dequeue):
- Check . It is empty. Transfer remaining elements from to .
- Pop 4 from and push to . .
- Pop the top of (4).
- State: , .
1. :
- Push each item onto the stack as it arrives.
- State: , .
2. (First Dequeue):
- Check the stack. It is empty.
- Transfer all elements from to by popping from and pushing to .
- Popping 3, then 2, then 1 from and pushing them to results in (with 1 at the top).
- Pop the top of (1).
- State: , .
3. :
- Push 4 directly onto the stack (do not touch ).- State: , .
4. (Second Dequeue):
- Check the stack. It is not empty ( with 2 at the top).
- Pop the top of (2) directly without touching .
- State: , .
5. (Third Dequeue):
- Pop the next item from (3).
- State: , .
6. (Fourth Dequeue):
- Check . It is empty. Transfer remaining elements from to .
- Pop 4 from and push to . .
- Pop the top of (4).
- State: , .
Result:
The dequeue outputs are 1, then 2, then 3, then 4. FIFO order is perfectly maintained.
The dequeue outputs are 1, then 2, then 3, then 4. FIFO order is perfectly maintained.
Try this: Trace the stack states for: enqueue(5); dequeue(); enqueue(6); dequeue(). Assume starting from empty stacks.
Practice
Predicting the Intermediate Stack State After Enqueue 4
Phase 4: Practice State Tracking
Now it is time to test your mental model against a specific moment in our locked sequence. Recall our working flow: we enqueued (all landing in the input stack), performed one dequeue (which flipped them into the output stack as from bottom to top and popped 1), and then enqueued 4.
Take a moment to reason through where that new element 4 lives right now. Does it go straight to the output stack to keep it full, or does it wait in the input stack while the remaining items (2 and 3) drain from the output stack? Write down or mentally picture the exact contents of both the input stack and output stack right before the next dequeue operation occurs.
Current operation sequence:
1.enqueue(1), enqueue(2), enqueue(3)
2.dequeue() -> returns 1
3.enqueue(4)
Question: What are the exact contents of the input stack and output stack immediately after enqueue(4) is completed?
Apply
Applying the Two-Stack Pattern to History Undo and Stream Buffering
Phase 5: Apply
Now that you have traced the exact state changes for our locked sequence—where entered
in, flipped to out, and handled incoming 4 while out still drained—let us look at where else this exact structural trick lives. The core pattern of a Two-Stack Queue is not just an interview quirk; it is a general technique for turning batch-reversal costs into amortized cheap operations whenever you must reconcile Last-In-First-Out hardware with First-In-First-Out consumption.Consider a real-time text editor or a video game command buffer receiving rapid user input while simultaneously flushing network packets. If you need to process commands in strict chronological order but your incoming socket buffer writes to the back of a LIFO memory pool, applying the two-stack model lets you buffer incoming events in
in and batch-flush them to out only when the consumer demands them. This guarantees that your worst-case flush is amortized across operations, resulting in a reliable average time per command.To test your mastery of this structural transfer, answer the following scenario-based challenge using the exact principles you learned while tracing our locked sequence.
FAQ
What is the expected dequeue sequence for the example: enqueue 1,2,3; dequeue; enqueue 4; dequeue three times?
The first dequeue removes 1. After enqueueing 4, the subsequent three dequeues will yield 2, then 3, and finally 4 in strict FIFO order.
Why do we need two stacks to implement a queue?
A stack is LIFO (Last-In, First-Out) while a queue is FIFO (First-In, First-Out). By using an 'in' stack for pushes and an 'out' stack for pops, we reverse the stack order twice to achieve FIFO behavior.
What is the time complexity of dequeue in a two-stack queue?
While the worst-case time complexity for a single dequeue is O(N) when the 'out' stack is empty and elements must be transferred from the 'in' stack, the amortized time complexity per operation is O(1).
When should I transfer elements from the 'in' stack to the 'out' stack?
Elements should only be transferred from the 'in' stack to the 'out' stack when a dequeue or peek operation is requested and the 'out' stack is completely empty.