Problem
Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push
, peek
, pop
, and empty
).
Implement the MyQueue
class:
void push(int x)
Pushes element x to the back of the queue.int pop()
Removes the element from the front of the queue and returns it.int peek()
Returns the element at the front of the queue.boolean empty()
Returnstrue
if the queue is empty,false
otherwise.
Notes:
- You must use only standard operations of a stack, which means only
push to top
,peek/pop from top
,size
, andis empty
operations are valid. - Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack’s standard operations.
This problem is opposite of Implement stack using queues.
Follow Up
Follow-up: Can you implement the queue such that each operation is amortized O(1)
time complexity? In other words, performing n
operations will take overall O(n)
time even if one of those operations may take longer.
Examples
Example 1:
|
|
Solution
Method 1 - Using 2 Stacks (Making costly dequeue)
We’ll implement a FIFO queue using two stacks. Lets call the stacks Instack and Outstack.
Logic
Enqueue
- An element is inserted in the queue by pushing it into the Instack.
Dequeue
- An element is extracted from the queue by popping it from the Outstack.
- If the Outstack is empty then all elements currently in Instack are transferred to Outstack but in the reverse order.
Code
|
|
Complexity
Time Complexity:
- Push -
O(1)
- Pop -
O(N)
- Top -
O(1)
- Stack Size -
O(1)
Dry Run
- Enqueue 3, 4,
- Dequeue
- Enqueue 5, 6
- Dequeue
- Dequeue
At step 1, InStack={4, 3} , OutStack = {}. Top in stack points to 4. At step 2, InStack={} , OutStack{3, 4}, note that order is reversed. Top points to 3. Now, we pop the item, hence we pop out 3. OutStack={4} At Step 3, InStack={6, 5}, OutStack={4} At Step 4, InStack={6, 5}, OutStack={}, 4 is popped out of OutStack At Step 5, again, InStack={}, OutStack={5, 6} = OutStack{6} , and 5 is popped out.
Method 2 - Using 2 Stacks (with costly enqueue)
Logic
Enqueue
|
|
Dequeue
|
|
Code
|
|
Complexity
Time Complexity:
- Push -
O(N)
- Pop -
O(1)
- Top -
O(1)
- Stack Size -
O(1)
Method 3 - Using 1 Stack (and Another Recursion stack)
But can we implement queue, using 1 stack only? Answer is yes, We can have 1 primary stack. We can get another temporary stack using call stack of recursion.
Steps remain the same:
- You need to transfer elements from one stack to another temporary stack, to reverse their order.
- Then push the new element to be inserted, onto the temporary stack
- Then transfer the elements back to the original stack
- The new element will be on the bottom of the stack, and the oldest element is on top (first to be popped)
Here is the code in java:
|
|