232. Implement Queue using Stacks (E)
https://leetcode.com/problems/implement-queue-using-stacks/
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:
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
implement it by two stacks, do not use any other data structure and push, pop and top should be O(1) by AVERAGE.
2.Code
首先,队列的 API 如下:
我们使用两个栈 s1, s2
就能实现一个队列的功能(这样放置栈可能更容易理解):
当调用 push
让元素入队时,只要把元素压入 s1
即可,比如说 push
进 3 个元素分别是 1,2,3,那么底层结构就是这样:
那么如果这时候使用 peek
查看队头的元素怎么办呢?按道理队头元素应该是 1,但是在 s1
中 1 被压在栈底,现在就要轮到 s2
起到一个中转的作用了:当 s2
为空时,可以把 s1
的所有元素取出再添加进 s2
,这时候 s2
中元素就是先进先出顺序了。
同理,对于 pop
操作,只要操作 s2
就可以了。
最后,如何判断队列是否为空呢?如果两个栈都为空的话,就说明队列为空:
至此,就用栈结构实现了一个队列,核心思想是利用两个栈互相配合。
值得一提的是,这几个操作的时间复杂度是多少呢?有点意思的是 peek
操作,调用它时可能触发 while
循环,这样的话时间复杂度是 O(N),但是大部分情况下 while
循环不会被触发,时间复杂度是 O(1)。由于 pop
操作调用了 peek
,它的时间复杂度和 peek
相同。
像这种情况,可以说它们的最坏时间复杂度是 O(N),因为包含 while
循环,可能需要从 s1
往 s2
搬移元素。
但是它们的均摊时间复杂度是 O(1),这个要这么理解:对于一个元素,最多只可能被搬运一次,也就是说 peek
操作平均到每个元素的时间复杂度是 O(1)。
Version 2:
Last updated