Description
Implement a last-in-first-out (LIFO) stack using only two queues. The implemented stack should support all the functions of a normal stack (push
, top
, pop
, and empty
).
Implement the MyStack
class:
void push(int x)
Pushes element x to the top of the stack.int pop()
Removes the element on the top of the stack and returns it.int top()
Returns the element on the top of the stack.boolean empty()
Returnstrue
if the stack is empty,false
otherwise.
Notes:
- You must use only standard operations of a queue, which means that only
push to back
,peek/pop from front
,size
andis empty
operations are valid. - Depending on your language, the queue may not be supported natively. You may simulate a queue using a list or deque (double-ended queue) as long as you use only a queue’s standard operations.
Examples:
Example 1:
Input
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 2, 2, false]
Explanation
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // return 2
myStack.pop(); // return 2
myStack.empty(); // return False
Solution in Python
Approach:
- Two Queues:
- Use two queues
queue1
andqueue2
. queue1
will always be used to store elements in the correct order for stack operations.queue2
will temporarily store elements when reordering is required after apush
.
- Use two queues
- Push Operation:
- Add the new element to
queue2
. - Then, move all elements from
queue1
toqueue2
, making the most recently added element the front element of the queue. - Swap
queue1
andqueue2
, soqueue1
always contains the elements in the correct order for LIFO access.
- Add the new element to
- Pop Operation:
- Directly remove the front element from
queue1
.
- Directly remove the front element from
- Top Operation:
- Peek at the front element of
queue1
.
- Peek at the front element of
- Empty Operation:
- Check if
queue1
is empty.
- Check if
Time Complexity:
- Push: O(n) due to reordering.
- Pop, Top, and Empty: O(1).
Space Complexity:
- O(n), where
n
is the number of elements in the stack.
Python
from collections import deque
class MyStack:
def __init__(self):
# Initialize two queues
self.queue1 = deque() # Main queue to store stack elements
self.queue2 = deque() # Temporary queue used during push operation
def push(self, x: int) -> None:
# Push the new element into queue2
self.queue2.append(x)
# Move all elements from queue1 to queue2 to ensure the last pushed element is on top
while self.queue1:
self.queue2.append(self.queue1.popleft())
# Swap the names of the queues so queue1 becomes the main queue again
self.queue1, self.queue2 = self.queue2, self.queue1
def pop(self) -> int:
# Remove and return the top element, which is the front of queue1
return self.queue1.popleft()
def top(self) -> int:
# Return the top element without removing it, which is the front of queue1
return self.queue1[0]
def empty(self) -> bool:
# Check if the stack (queue1) is empty
return not self.queue1
Explanation of Functions:
__init__()
:- Initializes two empty queues,
queue1
andqueue2
usingdeque
(double-ended queue) from Python’scollections
module.deque
supports fast appends and pops from both ends.
- Initializes two empty queues,
push(x)
:- Adds the new element
x
toqueue2
. - Transfers all elements from
queue1
toqueue2
so that the last added element is at the front. - Swaps
queue1
andqueue2
to maintain the correct stack order inqueue1
.
- Adds the new element
pop()
:- Removes and returns the front element of
queue1
, which is the top element of the stack.
- Removes and returns the front element of
top()
:- Returns the front element of
queue1
without removing it, which represents the top of the stack.
- Returns the front element of
empty()
:- Returns
True
ifqueue1
is empty, otherwise returnsFalse
.
- Returns
Solution in Javascript
JavaScript
var MyStack = function() {
// Initialize two queues
this.queue1 = [];
this.queue2 = [];
};
/**
* @param {number} x
* @return {void}
*/
MyStack.prototype.push = function(x) {
// Push the new element into queue2
this.queue2.push(x);
// Move all elements from queue1 to queue2 to reorder them
while (this.queue1.length > 0) {
this.queue2.push(this.queue1.shift());
}
// Swap the references of queue1 and queue2
[this.queue1, this.queue2] = [this.queue2, this.queue1];
};
/**
* @return {number}
*/
MyStack.prototype.pop = function() {
// Remove and return the front element of queue1, which is the stack's top element
return this.queue1.shift();
};
/**
* @return {number}
*/
MyStack.prototype.top = function() {
// Return the front element of queue1 without removing it
return this.queue1[0];
};
/**
* @return {boolean}
*/
MyStack.prototype.empty = function() {
// Return true if queue1 is empty, false otherwise
return this.queue1.length === 0;
};
Solution in Java
Java
import java.util.LinkedList;
import java.util.Queue;
class MyStack {
// Two queues to implement stack
private Queue<Integer> queue1;
private Queue<Integer> queue2;
// Constructor to initialize the stack
public MyStack() {
queue1 = new LinkedList<>(); // Main queue holding elements in stack order
queue2 = new LinkedList<>(); // Temporary queue used during push operation
}
// Push element x onto stack
public void push(int x) {
// Step 1: Add the new element to queue2
queue2.add(x);
// Step 2: Move all elements from queue1 to queue2 to maintain LIFO order
while (!queue1.isEmpty()) {
queue2.add(queue1.remove());
}
// Step 3: Swap queue1 and queue2 so queue1 contains the updated elements
Queue<Integer> temp = queue1;
queue1 = queue2;
queue2 = temp; // Now queue1 is the main queue and queue2 is empty again
}
// Remove and return the element on top of the stack
public int pop() {
// Remove the front element of queue1, which represents the top of the stack
return queue1.remove();
}
// Return the top element of the stack without removing it
public int top() {
// Peek at the front element of queue1, which represents the top of the stack
return queue1.peek();
}
// Check if the stack is empty
public boolean empty() {
// If queue1 is empty, then the stack is empty
return queue1.isEmpty();
}
}
Solution in C#
C#
using System.Collections.Generic;
public class MyStack {
private Queue<int> queue1; // Main queue that holds stack elements
private Queue<int> queue2; // Temporary queue used for push operations
// Constructor to initialize the stack
public MyStack() {
queue1 = new Queue<int>();
queue2 = new Queue<int>();
}
// Push element x onto the stack
public void Push(int x) {
// Add the new element to queue2
queue2.Enqueue(x);
// Move all elements from queue1 to queue2
while (queue1.Count > 0) {
queue2.Enqueue(queue1.Dequeue());
}
// Swap queue1 and queue2 so that queue1 holds the correct order
Queue<int> temp = queue1;
queue1 = queue2;
queue2 = temp;
}
// Remove and return the element on the top of the stack
public int Pop() {
// Remove and return the front element of queue1
return queue1.Dequeue();
}
// Return the top element of the stack without removing it
public int Top() {
// Return the front element of queue1
return queue1.Peek();
}
// Check if the stack is empty
public bool Empty() {
// Return true if queue1 is empty
return queue1.Count == 0;
}
}