Fuck LeetCode > Stack and Queue > 232. Implement Queue using Stacks > Solved in Python, JavaScript, Java, C++, C#, Go, Ruby > Repost or Contribute
LeetCode link: 232. Implement Queue using Stacks, difficulty: Easy.
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.
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
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
Constraints:
1 <= x <= 9
- At most
100
calls will be made topush
,pop
,peek
, andempty
. - All the calls to
pop
andpeek
are valid.
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.
Intuition
To implement a queue with two stacks, the intuitive idea is that one stack
stack_in
is dedicated topush
, and the other stackstack_out
is dedicated topop
.Push
can be easy, justpush
directly, thenpop
is not so easy. How to do it?
Click to view the answer
Stack is last in first out, queue is first in first out, the two are opposite, so it is not possible to
pop
directly fromstack_in
. You have to add the elements instack_in
tostack_out
in reverse, and thenpop
.
Complexity
Time complexity
push O(1), pop O(1), peek O(1), empty O(1)
Space complexity
O(n)
Explanation
pop
and peek
appear to be O(n)
, but they are actually O(1)
. This is because if dump_into_stack_out
operates on m
numbers at a time, then each pop
operation for the next m
times is O(1)
.
Python #
class MyQueue:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
self.stack_in.append(x)
def pop(self) -> int:
self.dump_into_stack_out_if_it_is_empty()
return self.stack_out.pop()
def peek(self) -> int:
self.dump_into_stack_out_if_it_is_empty()
return self.stack_out[-1]
def empty(self) -> bool:
return not self.stack_out and not self.stack_in
def dump_into_stack_out_if_it_is_empty(self) -> int:
if not self.stack_out:
while self.stack_in:
self.stack_out.append(self.stack_in.pop())
JavaScript #
var MyQueue = function () {
this.stackIn = []
this.stackOut = []
};
MyQueue.prototype.push = function (x) {
this.stackIn.push(x)
};
MyQueue.prototype.pop = function () {
this.dumpIntoStackOutWhenItIsEmpty()
return this.stackOut.pop()
};
MyQueue.prototype.peek = function () {
this.dumpIntoStackOutWhenItIsEmpty()
return this.stackOut.at(-1)
};
MyQueue.prototype.empty = function () {
return this.stackOut.length === 0 && this.stackIn.length === 0
};
MyQueue.prototype.dumpIntoStackOutWhenItIsEmpty = function () {
if (this.stackOut.length === 0) {
while (this.stackIn.length > 0) {
this.stackOut.push(this.stackIn.pop())
}
}
}
Java #
import java.util.Stack;
class MyQueue {
private Stack<Integer> stackIn;
private Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<>();
stackOut = new Stack<>();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpIntoStackOutWhenItIsEmpty();
return stackOut.pop();
}
public int peek() {
dumpIntoStackOutWhenItIsEmpty();
return stackOut.peek();
}
public boolean empty() {
return stackIn.empty() && stackOut.empty();
}
private void dumpIntoStackOutWhenItIsEmpty() {
if (stackOut.empty()) {
while (!stackIn.empty()) {
stackOut.push(stackIn.pop());
}
}
}
}
C++ #
class MyQueue {
private:
stack<int> stack_in_;
stack<int> stack_out_;
void dumpIntoStackOutWhenItIsEmpty() {
if (stack_out_.empty()) {
while (!stack_in_.empty()) {
stack_out_.push(stack_in_.top());
stack_in_.pop();
}
}
}
public:
MyQueue() {}
void push(int x) {
stack_in_.push(x);
}
int pop() {
dumpIntoStackOutWhenItIsEmpty();
int value = stack_out_.top();
stack_out_.pop();
return value;
}
int peek() {
dumpIntoStackOutWhenItIsEmpty();
return stack_out_.top();
}
bool empty() {
return stack_in_.empty() && stack_out_.empty();
}
};
C# #
using System.Collections.Generic;
public class MyQueue
{
private Stack<int> stackIn;
private Stack<int> stackOut;
public MyQueue()
{
stackIn = new Stack<int>();
stackOut = new Stack<int>();
}
public void Push(int x)
{
stackIn.Push(x);
}
public int Pop()
{
DumpIntoStackOutWhenItIsEmpty();
return stackOut.Pop();
}
public int Peek()
{
DumpIntoStackOutWhenItIsEmpty();
return stackOut.Peek();
}
public bool Empty()
{
return stackIn.Count == 0 && stackOut.Count == 0;
}
private void DumpIntoStackOutWhenItIsEmpty()
{
if (stackOut.Count == 0)
{
while (stackIn.Count > 0)
{
stackOut.Push(stackIn.Pop());
}
}
}
}
Go #
type MyQueue struct {
stackIn []int
stackOut []int
}
func Constructor() MyQueue {
return MyQueue{
stackIn: make([]int, 0),
stackOut: make([]int, 0),
}
}
func (this *MyQueue) Push(x int) {
this.stackIn = append(this.stackIn, x)
}
func (this *MyQueue) Pop() int {
this.dumpIntoStackOutWhenItIsEmpty()
top := this.stackOut[len(this.stackOut) - 1]
this.stackOut = this.stackOut[:len(this.stackOut) - 1]
return top
}
func (this *MyQueue) Peek() int {
this.dumpIntoStackOutWhenItIsEmpty()
return this.stackOut[len(this.stackOut) - 1]
}
func (this *MyQueue) Empty() bool {
return len(this.stackIn) == 0 && len(this.stackOut) == 0
}
func (this *MyQueue) dumpIntoStackOutWhenItIsEmpty() {
if len(this.stackOut) == 0 {
for len(this.stackIn) > 0 {
top := this.stackIn[len(this.stackIn) - 1]
this.stackIn = this.stackIn[:len(this.stackIn) - 1]
this.stackOut = append(this.stackOut, top)
}
}
}
Ruby #
class MyQueue
def initialize
@stack_in = []
@stack_out = []
end
def push(x)
@stack_in.push(x)
end
def pop
dump_into_stack_out_when_it_is_empty
@stack_out.pop
end
def peek
dump_into_stack_out_when_it_is_empty
@stack_out.last
end
def empty
@stack_in.empty? && @stack_out.empty?
end
private
def dump_into_stack_out_when_it_is_empty
if @stack_out.empty?
while !@stack_in.empty?
@stack_out.push(@stack_in.pop)
end
end
end
end