我们都知道这两个数据结构很相似,但是又有差别,
就好像是对立统一的一样.
栈是一种后进先出的数据结构,元素从顶端入栈,然后从顶端出栈。
队列是一种先进先出的数据结构,元素从后端入队,然后从前端出队。
首先我们都知道用Python的list去实现不管是队列还是stack都是很简单的,毕竟list四面开口,想不会都难…
用栈去实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek()
返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false
思路就是双栈.
一个负责入队.
一个负责出队.
class MyQueue(object):
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, x):
self.stack1.append(x)
def pop(self):
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
def peek(self):
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]
def empty(self):
return not self.stack1 and not self.stack2
这里比较重要的是要一直维持一个stack1 作为存储.
这个迭代其实还是很难理解的.
stack1 中其实存储的是最后一次出队之后入队的所有值.
stack2 其实是最后一次出队之后的第一次入队之前还没有出队的值.
所以这样的话判断空的条件就变成了两者都是空了.这是比较难的.
没有老衲的点拨.诸位半小时内想不出来…
有了老衲的电波.诸位一天都想不出来…因为我觉得我的读者和我没有眼缘…😄
用队列去实现栈
class MyStack:
def __init__(self):
"""
Initialize your data structure here.
"""
self.queue1 = collections.deque()
self.queue2 = collections.deque()
def push(self, x: int) -> None:
"""
Push element x onto stack.
"""
self.queue2.append(x)
while self.queue1:
self.queue2.append(self.queue1.popleft())
self.queue1, self.queue2 = self.queue2, self.queue1
def pop(self) -> int:
"""
Removes the element on top of the stack and returns that element.
"""
return self.queue1.popleft()
def top(self) -> int:
"""
Get the top element.
"""
return self.queue1[0]
def empty(self) -> bool:
"""
Returns whether the stack is empty.
"""
return not self.queue1
值得注意的两点.
1.这里为什么申请了两个队列?
很简单,一个是用作中间存储,存储已经满足stack条件的数据的!!!
2.为什么这两个队列push完了要交换回来?
为了满足整体的迭代.我们不是要push一次.下一次push的时候我们要保证
queue1 中已经满足了stack的特征.
当然也可以不用中间存储啦
如下:
n = len(self.queue)
self.queue.append(x)
for _ in range(n):
self.queue.append(self.queue.popleft())
但是要注意顺序.x是不参与先出后入的
总结
其实都是重点是增加值的过程中需要改变.其他的都还好.