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).
LeetCode-232: 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()
: Returns true if the queue is empty, false otherwise.Notes:
list
or deque
(double-ended queue) as long as you use only a stack’s standard operations.Before jumping into the solution, let us first recall the difference between two data structures:
To implement a queue using two stacks, we need to simulate a FIFO behavior using two data structures of LIFO nature. There are two approaches to achieve the same.
push
and pop
The overall idea is to maintain the order of elements in the stack by moving the elements from the primary stack to the secondary stack and vice-versa. This will help us to achieve the FIFO behavior of the queue.
Complexity Analysis: As we are moving all the elements already pushed to the primary stack on every push
method call, the time complexity for the push
operation is \(O(n)\) and for the pop
, peek
, and empty
operations is \(O(1)\)
class MyQueue {
private final Stack<Integer> primary;
private final Stack<Integer> secondary;
public MyQueue() {
primary = new Stack<>();
secondary = new Stack<>();
}
public void push(int x) {
while(!primary.isEmpty()){
secondary.push(primary.pop());
}
primary.push(x);
while(!secondary.isEmpty()){
primary.push(secondary.pop());
}
}
public int pop() {
return primary.pop();
}
public int peek() {
return primary.peek();
}
public boolean empty() {
return primary.isEmpty();
}
}
push
and pop
In this approach, we will use two stacks - one for pushing the elements and the other for popping the elements. The primary stack will be used for pushing the elements and the secondary stack will be used for popping the elements.
The steps for the operations are as follows:
Complexity Analysis: The time complexity for the push
and empty
operations is \(O(1)\) and for the pop
, peek
, operations, it is \(O(n)\).
But if we look at the amortized time complexity, the time complexity for the pop
and peek
operations is \(O(1)\) as we are moving the elements from the primary stack to the secondary stack only when the secondary stack is empty.
The worst-case time complexity for the pop
and peek
operations is \(O(n)\) only when the secondary stack is empty which happens only once for every \(n\) elements pushed to the primary stack.
class MyQueue {
private final Stack<Integer> primary;
private final Stack<Integer> secondary;
public MyQueue() {
primary = new Stack<>();
secondary = new Stack<>();
}
public void push(int x) {
primary.push(x);
}
public int pop() {
if(secondary.isEmpty()){
while(!primary.isEmpty()){
secondary.push(primary.pop());
}
}
return secondary.pop();
}
public int peek() {
if(secondary.isEmpty()){
while(!primary.isEmpty()){
secondary.push(primary.pop());
}
}
return secondary.peek();
}
public boolean empty() {
return primary.isEmpty() && secondary.isEmpty();
}
}
Be notified of new posts. Subscribe to the RSS feed.