Implement Queue using Stacks easy
Problem Statement
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:
MyQueue()
Initializes theMyQueue
object.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.
Example 1:
Input
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]
Explanation
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
Example 2:
Input:
["MyQueue", "push", "pop", "empty"]
[[], [1], [], []]
Output: [null,null,1,false]
Steps:
-
Initialization: We'll use two stacks,
stack1
andstack2
.stack1
will be the primary stack for pushing elements.stack2
will be used as a temporary stack to help withpop
andpeek
operations. -
push(x)
: Simply push the elementx
ontostack1
. -
pop()
:- If
stack2
is empty, transfer all elements fromstack1
tostack2
(reversing their order). - Pop and return the top element from
stack2
.
- If
-
peek()
:- If
stack2
is empty, transfer all elements fromstack1
tostack2
. - Return the top element of
stack2
.
- If
-
empty()
: ReturnTrue
if bothstack1
andstack2
are empty; otherwise, returnFalse
.
Explanation:
The key idea is to use stack2
to efficiently retrieve the front element of the queue. Since stacks operate in LIFO (Last-In, First-Out) order, we shift elements from stack1
to stack2
to reverse the order, effectively making the original front element the top of stack2
. This allows us to retrieve the front element in O(1) time after the initial transfer (which is amortized O(1) over many operations).
Code:
class MyQueue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, x: int) -> None:
self.stack1.append(x)
def pop(self) -> int:
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
def peek(self) -> int:
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]
def empty(self) -> bool:
return not self.stack1 and not self.stack2
Complexity:
- Time complexity:
push(x)
: O(1)pop()
: Amortized O(1). In the worst case, all elements fromstack1
are transferred tostack2
, but this only happens once for each element in the queue.peek()
: Amortized O(1). Similar reasoning topop()
.empty()
: O(1)
- Space complexity: O(N), where N is the number of elements in the queue. We use two stacks to store the elements.