📦 Implement Stack using Queue #225
Design a data structure MyStack that simulates the behavior of a stack, but internally uses only one or more queue(s).
You must implement the following operations:
| Function | Description |
|---|---|
void push(int x) |
Push element x onto the stack |
int pop() |
Removes and returns the element on top of the stack |
int top() |
Returns the element currently at the top of the stack |
bool empty() |
Returns whether the stack is empty |
Constraints:
- Only standard queue operations are allowed (
push,pop,front,size,empty). - You cannot use deque, list, or any stack methods.
A stack works as: 👉 Last in, first out (LIFO) A queue works as: 👉 First in, first out (FIFO)
So we need to “reverse” the natural order of the queue when inserting elements.
We can maintain one single queue, and every time we push a new element, we rotate the queue so that this new element comes to the front — effectively making it the top of the stack.
| Step | Queue State (front → back) | Explanation |
|---|---|---|
| Push 1 | [1] | Only one element |
| Push 2 | [2, 1] | After pushing 2, rotate 1 to the back |
| Push 3 | [3, 2, 1] | After pushing 3, rotate 2, 1 to back |
Now the front of the queue always acts as the top of the stack.
-
Store the current queue size
s. -
Push the new element
x. -
Rotate the queue
stimes:- Pop the front element and push it to the back.
-
Now the new element
xbecomes the front (the "top" of the stack).
- Simply pop the front element of the queue (this is the stack’s top).
- Return the front element of the queue (this is the top element).
- Return
trueif the queue is empty.
#include <queue>
using namespace std;
// Stack implemented using a single queue
class MyStack {
private:
queue<int> q; // internal queue
public:
MyStack() { }
// Push element x onto stack
void push(int x) {
int s = q.size(); // current size before adding
q.push(x); // push new element at back
// Rotate the queue to move new element to front
for (int i = 0; i < s; i++) {
q.push(q.front());
q.pop();
}
}
// Removes and returns the top element
int pop() {
int top = q.front(); // top is at the front
q.pop();
return top;
}
// Get the top element (without removing it)
int top() {
return q.front();
}
// Returns true if stack is empty
bool empty() {
return q.empty();
}
};| Operation | Time Complexity | Space Complexity | Explanation |
|---|---|---|---|
push() |
O(n) | O(n) | Because we rotate the queue after each push |
pop() |
O(1) | O(1) | Just pops from the queue front |
top() |
O(1) | O(1) | Returns front element |
empty() |
O(1) | O(1) | Returns q.empty() |
This approach trades push speed for pop simplicity.
We could also make push O(1) and pop O(n) using two queues:
push(x): simply enqueue inq1.pop(): move all elements except last fromq1toq2, pop the last, then swapq1andq2.
This reverses the trade-off:
| Version | Push | Pop |
|---|---|---|
| One Queue (current) | O(n) | O(1) |
| Two Queues | O(1) | O(n) |
MyStack st;
st.push(10);
st.push(20);
st.push(30);| Operation | Queue (front → back) | Top of stack |
|---|---|---|
| push(10) | [10] | 10 |
| push(20) | [20, 10] | 20 |
| push(30) | [30, 20, 10] | 30 |
Now:
st.top(); // returns 30
st.pop(); // removes 30
st.top(); // now returns 20MyStack st;
st.push(1);
st.push(2);
cout << st.top(); // 2
cout << st.pop(); // 2
cout << st.empty(); // false
cout << st.pop(); // 1
cout << st.empty(); // trueMyStack st;
st.push(42);
cout << st.top(); // 42
cout << st.pop(); // 42
cout << st.empty(); // trueMyStack st;
st.push(5);
st.push(7);
st.push(9);
st.pop(); // removes 9
st.push(11);
cout << st.top(); // 11- Push rotation trick: Always rotate the queue right after push so
frontalways represents stack top. - Alternative optimization: If your environment allows two queues, you can choose between O(n) push or O(n) pop.
- General idea: “Stack using queue” is a mirror-problem of “Queue using stacks” (LeetCode 225 vs 232).
- 225. Implement Stack using Queues (this exact problem on LeetCode)
- 232. Implement Queue using Stacks (the opposite)
- Design a Deque using stacks/queues — extension of both behaviors.
- Thread-safe stack/queue — add synchronization primitives for multithreading.
Q: Why rotate the queue in push?
A: Because new elements enter at the back by default. Rotating ensures that new elements end up at the front, representing the top of the stack.
Q: Can I use two queues instead of one? A: Yes — but you’ll need to transfer elements between them to simulate stack order. It works fine but requires more memory.
Q: Why is push O(n)? Can we make it faster?
A: We can’t avoid O(n) total cost because we must invert the order at some point — either at push or pop. This version chooses to pay the cost on push, keeping pop() simple and constant time.
Q: How can I visualize the rotation? A: After adding a new element, move all existing elements behind it — this puts the new element in front, like flipping a stack upside down each time you add a plate.
| Method | Data Structures | Push | Pop | Top | Extra Space | Simplicity |
|---|---|---|---|---|---|---|
| Single Queue (current) | 1 queue | O(n) | O(1) | O(1) | O(n) | ✅ Simple |
| Two Queues | 2 queues | O(1) | O(n) | O(n) | O(2n) | Slightly longer code |