Implement Stack Using Queue in DSA Javascript - Time & Space Complexity
We want to understand how the time needed changes when we use a queue to build a stack.
Specifically, how long does each stack operation take when done with queues?
Analyze the time complexity of the following stack push operation using a single queue.
class Stack {
constructor() {
this.queue = [];
}
push(x) {
this.queue.push(x);
let size = this.queue.length;
while (size > 1) {
this.queue.push(this.queue.shift());
size--;
}
}
pop() {
return this.queue.shift();
}
}
This code uses one queue to simulate a stack. The push operation moves elements to keep the newest on front.
Look at what repeats when pushing an element.
- Primary operation: The while loop that moves elements inside the queue.
- How many times: It runs once for each element already in the queue before the new one.
When the stack has more items, pushing takes longer because we move all old items behind the new one.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 moves inside the queue |
| 100 | About 99 moves inside the queue |
| 1000 | About 999 moves inside the queue |
Pattern observation: The number of moves grows directly with the number of items already in the stack.
Time Complexity: O(n)
This means pushing an item takes longer as the stack grows, roughly proportional to the stack size.
[X] Wrong: "Push operation is always fast because it just adds to the queue end."
[OK] Correct: Because we rotate all existing elements to keep stack order, push actually moves many items, making it slower as stack grows.
Understanding this helps you explain trade-offs when using one data structure to build another, a common interview skill.
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
To implement stack using queue, we reverse the order of elements in the queue to mimic LIFO behavior.Final Answer:
Use a queue to simulate stack operations by reversing order -> Option DQuick Check:
Stack via queue = reverse order [OK]
- Confusing stack with queue behavior
- Trying to implement queue using stack instead
- Ignoring order reversal needed for stack simulation
Solution
Step 1: Identify enqueue operation in JavaScript array
Enqueue means adding element at the end of the queue, which is done by push().Step 2: Check other methods
pop() removes from end, shift() removes from front, unshift() adds at front, so only push() adds at end.Final Answer:
queue.push(x); -> Option BQuick Check:
Enqueue = push() [OK]
- Using pop() instead of push() to add elements
- Using shift() or unshift() incorrectly for enqueue
- Confusing enqueue with dequeue operations
class Stack {
constructor() {
this.queue = [];
}
push(x) {
this.queue.push(x);
for (let i = 0; i < this.queue.length - 1; i++) {
this.queue.push(this.queue.shift());
}
}
pop() {
return this.queue.shift();
}
}
const s = new Stack();
s.push(1);
s.push(2);
s.push(3);
console.log(s.pop());
What will be printed?Solution
Step 1: Understand push operation
Push adds element at end, then rotates queue to move new element to front, simulating stack top.Step 2: Trace push and pop calls
Push 1: queue=[1]; Push 2: queue=[2,1]; Push 3: queue=[3,2,1]; Pop removes front, which is 3.Final Answer:
3 -> Option CQuick Check:
Stack pop = last pushed = 3 [OK]
- Assuming pop removes last element of array instead of front
- Not rotating queue after push
- Confusing queue shift() with stack pop()
class Stack {
constructor() {
this.q1 = [];
this.q2 = [];
}
push(x) {
this.q1.push(x);
}
pop() {
while (this.q1.length > 1) {
this.q2.push(this.q1.shift());
}
return this.q1.shift();
}
}Solution
Step 1: Analyze pop method
Pop moves all but last element from q1 to q2, then removes last from q1.Step 2: Identify missing step
After pop, q1 is empty and q2 has elements, but q1 and q2 are not swapped, so next pop fails.Final Answer:
pop() does not swap q1 and q2 after operation -> Option AQuick Check:
Swap queues after pop to maintain stack [OK]
- Forgetting to swap queues after pop
- Returning from wrong queue
- Incorrect initialization of queues
class Stack {
constructor() {
this.queue = [];
}
push(x) {
this.queue.push(x);
// What should be done here?
}
pop() {
return this.queue.shift();
}
}Solution
Step 1: Understand stack order with one queue
Stack is LIFO, but queue is FIFO, so after push, rotate queue to bring new element front.Step 2: Rotate queue after push
Remove elements from front and add them to back except the last pushed, so last pushed is at front.Final Answer:
Rotate the queue by dequeuing and enqueuing all elements except the last pushed -> Option AQuick Check:
Rotate queue after push to simulate stack [OK]
- Not rotating queue after push
- Trying to sort queue which is inefficient
- Assuming queue order matches stack without changes
Ready to prove it?
Pass the test and this pattern moves unknown
