Implement Stack Using Queue in DSA C++ - Time & Space Complexity
We want to understand how fast the stack operations run when we build a stack using a queue.
Specifically, how does the time to push or pop items grow as we add more elements?
Analyze the time complexity of the following code snippet.
#include <queue>
using namespace std;
class Stack {
queue<int> q;
public:
void push(int x) {
q.push(x);
int n = q.size();
for (int i = 0; i < n - 1; i++) {
q.push(q.front());
q.pop();
}
}
void pop() {
q.pop();
}
int top() {
return q.front();
}
bool empty() {
return q.empty();
}
};
This code uses one queue to simulate a stack. The push operation rearranges the queue so the newest element is always at the front.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop inside the push method that moves elements in the queue.
- How many times: It runs (n - 1) times where n is the current size of the queue.
Each push moves all existing elements behind the new one, so the work grows as the stack grows.
| Input Size (n) | Approx. Operations in push() |
|---|---|
| 10 | 9 moves |
| 100 | 99 moves |
| 1000 | 999 moves |
Pattern observation: The number of moves grows linearly with the number of elements already in the stack.
Time Complexity: O(n)
This means pushing an element takes longer as the stack grows, roughly proportional to the stack size.
[X] Wrong: "Push operation is always O(1) because queue push is O(1)."
[OK] Correct: Here, push rearranges the queue by moving all existing elements, so it takes O(n) time, not constant time.
Understanding how to build one data structure using another and analyzing its cost shows your problem-solving and reasoning skills.
"What if we used two queues instead of one? How would the time complexity of push and pop change?"
Practice
Solution
Step 1: Understand stack and queue behavior
A stack follows Last-In-First-Out (LIFO), while a queue follows First-In-First-Out (FIFO).Step 2: Simulate stack using queue
By reordering elements in a single queue after each push, the newest element is always at the front, simulating stack pop behavior.Final Answer:
Use one queue and reorder elements to simulate stack behavior -> Option CQuick Check:
Stack via queue = reorder elements [OK]
- Confusing stack with queue behavior
- Using two stacks instead of queues
- Not reordering queue after push
Solution
Step 1: Recall C++ STL queue declaration
The correct syntax uses template syntax: queue<int> q; declares a queue of integers.Step 2: Check syntax correctness
queue<int> q; matches the correct syntax; others have syntax errors or invalid declarations.Final Answer:
queue<int> q; -> Option BQuick Check:
Correct STL queue syntax = queue<int> q; [OK]
- Misplacing template brackets
- Using parentheses instead of semicolon
- Declaring queue as array
class Stack {
queue<int> q;
public:
void push(int x) {
q.push(x);
int n = q.size();
for (int i = 0; i < n - 1; i++) {
q.push(q.front());
q.pop();
}
}
int pop() {
int val = q.front();
q.pop();
return val;
}
};
int main() {
Stack s;
s.push(10);
s.push(20);
s.push(30);
cout << s.pop() << " ";
s.push(40);
cout << s.pop() << " ";
cout << s.pop() << " ";
return 0;
}Solution
Step 1: Trace push operations
Push 10: queue = [10]
Push 20: queue = [20, 10] after rotation
Push 30: queue = [30, 20, 10] after rotationStep 2: Trace pop and push
Pop: returns 30, queue = [20, 10]
Push 40: queue = [40, 20, 10]
Pop: returns 40, queue = [20, 10]
Pop: returns 20, queue = [10]Final Answer:
30 40 20 -> Option AQuick Check:
Stack pop order = 30, 40, 20 [OK]
- Not rotating queue after push
- Confusing queue front with stack top
- Incorrect pop order
class Stack {
queue<int> q1, q2;
public:
void push(int x) {
q1.push(x);
}
int pop() {
if (q1.empty()) return -1;
while (q1.size() > 1) {
q2.push(q1.front());
q1.pop();
}
int val = q1.front();
q1.pop();
swap(q1, q2);
return val;
}
};Solution
Step 1: Analyze pop operation logic
Pop moves all but last element from q1 to q2, then pops last element from q1, then swaps q1 and q2.Step 2: Check correctness of push and pop
Push adds to q1; pop removes last pushed element correctly by transferring elements and swapping queues.Final Answer:
Pop operation is correct; no error -> Option DQuick Check:
Two-queue stack pop logic = correct [OK]
- Swapping queues too early
- Pushing to wrong queue
- Not checking empty queue before pop
Solution
Step 1: Understand time complexity trade-offs
Push elements normally and rotate queue on each pop (push normally, rotate on pop) makes push O(1), pop O(n). Use a queue and a stack together for hybrid implementation is not pure queue. Use two queues to separate push and pop operations uses two queues, not single queue.Step 2: Optimize pop to O(1) with single queue
Enqueue new element, then dequeue and enqueue all previous elements to move new element to front. This makes pop O(1) as front is always top (matches Push elements by enqueueing and dequeueing all elements except the new one).Final Answer:
Push elements by enqueueing and dequeueing all elements except the new one -> Option AQuick Check:
Rotate queue after push for O(1) pop [OK]
- Trying to optimize pop without reordering queue
- Using two queues instead of one
- Mixing stack and queue data structures
Ready to prove it?
Pass the test and this pattern moves unknown
