一、题目
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, and is 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.
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.
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 falseConstraints:
1 <= x <= 9
- At most
100
calls will be made topush
,pop
,peek
, andempty
.- All the calls to
pop
andpeek
are valid.
二、思路
参考了大佬的这篇题解
栈是一种LIFO的数据结构,而队列是FIFO的数据结构,我们用栈实现队列就是LIFO => FIFO,我们可以用两个栈来实现。
首先我们定义一个栈stack1
用于存放原始的数据,即接收push()
方法操作的数据;
接着我们定义另外一个栈stack2
,并将stack1
中的数据使用pop()
方法传送到stack2
中,这样这个stack2
就类似于我们的队列了:
- 对于
stack1
来说,stack1
的栈顶元素第一个弹栈,stack1
的栈底元素是最后一个弹栈的; - 对于
stack2
来说,接收到的第一个元素(stack1
的栈顶元素)作为栈底元素,接收到的最后一个元素(stack
的栈底元素)作为栈顶元素; - 这样,当我们对
stack2
进行pop()
操作时,返回的数是我们第一个传入的数,即队列的第一个元素。
三、代码
class MyQueue:
def __init__(self):
"""
Initialize your data structure here.
"""
self.stack1 = []
self.stack2 = []
def push(self, x: int) -> None:
"""
Push element x to the back of queue.
"""
self.stack1.append(x)
def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
def peek(self) -> int:
"""
Get the front element.
"""
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]
def empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
return not self.stack1 and not self.stack2
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()