AlgoMaster Logo

Implement Stack using Queues

easyFrequency7 min readUpdated June 23, 2026

Understanding the Problem

We need to simulate a stack (LIFO) using only queues (FIFO). The two structures order their elements in opposite directions. A stack returns the most recently added element first; a queue returns the oldest element first.

The whole problem reduces to one question: how do we rearrange elements so a FIFO queue can serve them in LIFO order? Every solution shifts that rearranging cost to a different operation. We can pay it on every push (rearrange immediately so the front of the queue is always the newest element), or pay it on every pop (move elements aside to reach the newest one at retrieval time). The same idea also works with a single queue by rotating it after each push.

Key Constraints:

  • At most 100 calls across all operations. An O(n) operation runs at most 100 elements deep, so even quadratic total work is fine here. This is why we can freely pick the simplest correct rearrangement rather than optimizing for asymptotic balance.
  • All pop and top calls are valid, so we never have to handle an empty stack.

Approach 1: Two Queues (Push O(n), Pop O(1))

Intuition

Keep the queue in stack order at all times. If the front of the queue always holds the most recently pushed element, then pop and top reduce to reading the front.

To maintain that, we use two queues. When we push a new element, we put it into the empty secondary queue first, then move everything from the main queue behind it, one element at a time. This places the new element at the front, with all older elements lined up behind it in reverse order. We then swap the two queues so the secondary becomes the main.

The trade-off: every push costs O(n) because we move all existing elements, but pop and top are O(1) since the answer is always at the front.

Algorithm

  1. Maintain two queues: q1 (main) and q2 (helper).
  2. Push(x): Enqueue x into q2. Then dequeue every element from q1 and enqueue it into q2. Now q2 has elements in stack order with x at the front. Swap q1 and q2.
  3. Pop(): Dequeue from the front of q1 and return it.
  4. Top(): Peek at the front of q1 and return it.
  5. Empty(): Return whether q1 is empty.

Example Walkthrough

1Initial state: q1 = [], q2 = []
Front
Rear
1/6

Code

This approach makes push expensive and pop cheap. The next approach reverses that, delaying all rearranging until a pop happens.

Approach 2: Two Queues (Push O(1), Pop O(n))

Intuition

Instead of paying the cost during push, we defer it to pop. Push enqueues the element into q1 and does no rearranging.

The work happens during pop. The most recently pushed element sits at the back of the queue, so we dequeue all elements except the last one and move them into q2. The single element left in q1 is the one we return. We then swap q1 and q2 so the remaining elements are ready for the next operation.

This is the mirror image of Approach 1, and it wins when pushes far outnumber pops.

Algorithm

  1. Maintain two queues: q1 (main) and q2 (helper). Also track the topElement for O(1) top queries.
  2. Push(x): Enqueue x into q1. Update topElement = x.
  3. Pop(): Dequeue all elements from q1 except the last one, moving them to q2. Track the second-to-last element as the new topElement. Dequeue the final element from q1 (this is the stack's top). Swap q1 and q2. Return the final element.
  4. Top(): Return topElement.
  5. Empty(): Return whether q1 is empty.

Example Walkthrough

1Initial state: q1 = [], topElement = -1
Front
Rear
1/6

Code

Both approaches so far use two queues. The follow-up asks for a single-queue solution, which the next approach achieves by rotating one queue in place.

Approach 3: Single Queue (Push O(n), Pop O(1))

Intuition

The second queue is unnecessary. After pushing a new element to the back of a single queue, rotate the queue by dequeuing from the front and re-enqueuing at the back. Doing this exactly size - 1 times moves the new element to the front.

A circular conveyor belt is a useful picture. You place a new item at the end, then rotate the belt until that item reaches the front, while the older items keep their relative order behind it.

This single-queue rotation is the answer to the follow-up.

Algorithm

  1. Maintain a single queue q.
  2. Push(x): Enqueue x at the back of q. Then rotate: dequeue from the front and enqueue to the back, repeated size - 1 times. Now x is at the front.
  3. Pop(): Dequeue from the front of q and return it.
  4. Top(): Peek at the front of q and return it.
  5. Empty(): Return whether q is empty.

Example Walkthrough

1Initial state: q = []
Front
Rear
1/7

Code