225.用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
解题思路:
- 用两个队列实现栈,需要了解队列特性(先进先出)以及栈特性(先进后出)
- 在python中如何实现队列?用
collections.deque()功能,并且题目限制了队列的操作
push to back对应deque.append()peek/pop from front对应deque.popleft()size对应len()is empty,直接判断deque是否为空即可
- 用deque1作为存储队列,deque2作为辅助队列
详细代码:
class MyStack:
def __init__(self): # 1.import collections(力扣已经帮忙引入了),初始化队列
self.deque1 = collections.deque() #存储队列
self.deque2 = collections.deque() #辅助队列
def push(self, x: int) -> None:
self.deque2.append(x) # 2.辅助队列先加个x
while self.deque1: # 当存储队列存在元素时,将队列最左端的元素弹出,在放到辅助队列中
self.deque2.append(self.deque1.popleft())
self.deque1, self.deque2 = self.deque2, self.deque1 #存储队列与辅助队列对调,记得跳出while
def pop(self) -> int:
return self.deque1.popleft() #符合队列peek from front
def top(self) -> int:
return self.deque1[0]
def empty(self) -> bool:
return not self.deque1 # 注意题目要求,队列非空为true,但是题目要求如果为空是true
做题记录
- 花费40分钟:看官方题解且理解15分钟,代码实现5分钟,写题解20分钟
- 代码错误:
deque.popleft()括号中不带参数;push功能中注意while包含的范围;
- 情绪波动:总感觉自己学不会,而且这是刷第二次了吧,全都忘记了,不过先坚持两个月下来再说
232.用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
解题思路:
- 一开始效仿225题思路,想用一个存储deque以及辅助deque,不过发现不通过(现在还没有发现哪里错了),后来考虑用stack_in和stack_out来完成,也就是进栈和出栈合二为一一起看
代码实现:
第一次解题思路(没有通过):还没有找出错误点……
class MyQueue:
def __init__(self):
self.stack1 = collections.deque() # 双端队列表示栈
self.stack2 = collections.deque()
def push(self, x: int) -> None:
self.stack1.append(x)
def pop(self) -> int:
while self.stack1:
self.stack2.append(self.stack1.pop())
self.stack1, self.stack2 = self.stack2, self.stack1
return self.stack1.pop()
def peek(self) -> int:
return self.stack1[0]
def empty(self) -> bool:
return not self.stack1
第二个解题思路:
class MyQueue:
def __init__(self):
self.stackin = list() # 用列表表示栈
self.stackout = list()
def push(self, x: int) -> None:
self.stackin.append(x) #输入栈的append跟队列入队顺序是一样的
def pop(self) -> int:
if not self.stackout:
while self.stackin:
self.stackout.append(self.stackin.pop())
return self.stackout.pop()
def peek(self) -> int:
if not self.stackout:
while self.stackin:
self.stackout.append(self.stackin.pop())
return self.stackout[-1] #这里一开始有个错误!
def empty(self) -> bool:
return self.stackin == [] and self.stackout == []
做题记录:
- 全程50分钟:做题15分,讨论15分,记录20分
- 两道题的代码都可以很快敲出来,问题是什么情况下需要借用辅助列表从而完成一个完整的存储列表(用一完成一),以及什么时候将两个栈看成一个整体(二当成一)。这个思路还没有理清楚,不清楚应用场景
- 一个容易犯的错误!!
- 解答
peek(self)的是欧如果直接用return self.pop()的做法,会改变empty(self)算法改变了。可以迂回地处理如下:
def peek(self) -> int:
ans = self.pop() # 1获得队头的元素
self.stackout.append(ans) # 第一步弹出了,把他恢复
return ans
- 老实说刷完前一道题这一道题已经比较容易理解了,又觉得可以再坚持刷一刷