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.
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.pop and top calls are valid, so we never have to handle an empty stack.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.
q1 (main) and q2 (helper).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.q1 and return it.q1 and return it.q1 is empty.This approach makes push expensive and pop cheap. The next approach reverses that, delaying all rearranging until a pop happens.
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.
Elements enter q1 in push order, oldest at the front and newest at the back. A pop removes everything except the last element, and that last element is the newest one, which is what a stack returns. The elements moved to q2 keep their original relative order, so the next pop again finds the newest at the back.
The topElement variable avoids an O(n) scan on top. Push sets it to the new element. During pop, the loop assigns it the last value moved to q2, which is the second-to-last element of q1 and therefore the new top after the current top is removed.
q1 (main) and q2 (helper). Also track the topElement for O(1) top queries.x into q1. Update topElement = x.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.topElement.q1 is empty.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.
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.
The invariant is that the queue is always in stack order: front holds the newest element, back holds the oldest. A push appends x to the back, temporarily breaking the invariant, then rotates size - 1 times. Each rotation moves one of the older elements from front to back, so after size - 1 rotations every older element sits behind x, and the queue is back in stack order. Because push restores the invariant every time, pop and top read the correct element straight from the front.
q.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.q and return it.q and return it.q is empty.