请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
void push(int x)
将元素 x 推到队列的末尾int pop()
从队列的开头移除并返回元素int peek()
返回队列开头的元素boolean empty()
如果队列为空,返回true
;否则,返回false
说明:
- 你 只能 使用标准的栈操作 —— 也就是只有
push to top
,peek/pop from top
,size
, 和is empty
操作是合法的。 - 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
解题思路:
这题看着喝用栈实现队列很像,但是原理其实没那么通。
整体有点像这个图,链表是一头堵,所以两个链表,链表1直接最后入的先出输出到链表2就变成了先入留在栈底就实现了翻转,也就是先入先出。
但是队列1直接输出的是最早进入的直接输出到队列2也还是先入先出,所以方法不能照搬照抄。
所以这里的队列2可以用作缓存,在pop和top的时候把除了队列底部的最后一个数先放到队列2,这样就实现了后入先出,pop完再把队列2中的值还给队列1.
直接定义 self.front = [ ],不能用,因为pop()的时候不是从左端出来的,队列还是得用deque。
from collections import deque
class MyStack:
def __init__(self):
self.front = deque()
self.rear = deque()
self.size = 0
def push(self, x: int) -> None:
self.front.append(x)
self.size +=1
def pop(self) -> int:
if self.size == 0:
return None
for i in range(self.size-1):
self.rear.append(self.front.popleft())
x = self.front.popleft()
for i in range(self.size-1):
self.front.append(self.rear.popleft())
self.size -=1
return x
def top(self) -> int:
if self.size == 0:
return None
for i in range(self.size-1):
self.rear.append(self.front.popleft())
x = self.front.popleft()
self.rear.append(x)
for i in range(self.size):
self.front.append(self.rear.popleft())
return x
def empty(self) -> bool:
return self.size == 0
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()