Skip to content
BytePatterns

Queue From Two Stacks

Stacks & Queues: lesson 4 of 5

Reverse a reversal and LIFO turns into FIFO.

Lesson 4 of 5 · 5 min

Queue From Two Stacks

Step 1 of 11

Two stacks: arrivals pile up in the inbox, departures are served from the outbox.

The Idea

Keep an inbox stack for arrivals and an outbox stack for departures. When the outbox runs dry, pour the whole inbox into it — the order flips, so the oldest item now sits on top. Every item moves at most twice, which makes dequeue O(1) amortized.

Real-World Example

Deal a face-down deck card by card into a fresh pile and it comes out reversed: the bottom card ends up on top. Deal that pile once more and the deck is back exactly as it started. Two flips cancel out.

The Code

class Queue:
    def __init__(self):
        self.inbox, self.outbox = [], []
    def enqueue(self, x):
        self.inbox.append(x)              # always cheap
    def dequeue(self):
        if not self.outbox:               # refill only when empty
            while self.inbox:             # pour: the order flips
                self.outbox.append(self.inbox.pop())
        return self.outbox.pop()          # oldest sits on top

q = Queue()
for x in [1, 2, 3]:
    q.enqueue(x)
print(q.dequeue(), q.dequeue())           # 1 2

Your turn

What does this print?

inbox = [1, 2, 3]
outbox = []
while inbox:
  outbox.append(inbox.pop())
print(outbox)

Mini quiz

1 / 3

Why pour the inbox across only when the outbox is empty?