一、 232.用栈实现队列
1. 看完代码随想录的想法
(1)实现MyQueue类:必须定义两个栈,分别是进栈和出栈;
(2)调用进栈append()函数,将元素添加进入进栈内;
(3)定义判断空栈的函数,因为要求队列为空返回true,所以在调用进/出栈之前加上not;
(4)移除队列开头元素并将其返回:首先对self调用empty进行判断,如果为空,直接返回None;然后判断出栈是否为空,出栈如果不为空,则直接弹出元素,如果出栈为空,则需要将入栈的全部元素添加进入出栈中,入栈元素弹出,然后出栈添加元素,最后返回出栈的第一个元素;
(5)返回队列开头的元素:直接调用pop函数,将元素添加进出栈中,最终return即可。
class MyQueue:
# 实现 MyQueue 类:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
# void push(int x) 将元素 x 推到队列的末尾
self.stack_in.append(x)
def pop(self) -> int:
# int pop() 从队列的开头移除并返回元素
if self.empty():
return None
if self.stack_out:
return self.stack_out.pop()
else:
for i in range(len(self.stack_in)):
self.stack_out.append(self.stack_in.pop())
return self.stack_out.pop()
def peek(self) -> int:
# int peek() 返回队列开头的元素
ans = self.pop()
self.stack_out.append(ans)
return ans
def empty(self) -> bool:
# boolean empty() 如果队列为空,返回 true ;否则,返回 false
return not (self.stack_in or self.stack_out)
2. 实现过程中遇到的困难及解决
在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
最后如何判断队列为空:如果进栈和出栈都为空的话,说明模拟的队列为空了。
二、225. 用队列实现栈
1. 看完代码随想录的想法
法1 单队列法:一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。
法2 双队列法:队列是先进先出的,如果要在某队列中弹出最后一个元素,也就是第一个弹出最后一个元素,那么可以将前n-1个元素放进另一个队列,再弹出最后一个元素。
class MyStack:
# 实现 MyStack 类
def __init__(self):
self.que = deque()
def push(self, x: int) -> None:
# void push(int x) 将元素 x 压入栈顶
self.que.append(x)
def pop(self) -> int:
# int pop() 移除并返回栈顶元素
if self.empty():
return None
for i in range(len(self.que)-1):
self.que.append(self.que.popleft())
return self.que.popleft()
def top(self) -> int:
# int top() 返回栈顶元素
if self.empty():
return None
for i in range(len(self.que)-1):
self.que.append(self.que.popleft())
temp = self.que.popleft()
self.que.append(temp)
return temp
def empty(self) -> bool:
# boolean empty() 如果栈是空的,返回 true ;否则,返回 false
return not self.que
# 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()
三、20. 有效的括号
1. 看完代码随想录的想法
整体思路:
遍历字符串,看到左括号“(” ,就将右括号“ )”放进栈中;看到左方括号“[”,就将右方括号“]”放进栈中;看到左花括号“{”,就将右花括号“}”放进栈中;
如果遍历到右方向括号就与栈中括号做匹配,如果一直就弹出栈中括号,直到遍历完所有字符并且栈中元素为空,则说明完全匹配;
那么不匹配总共可能出现三种情况:A.遍历完成字符串,栈中还剩元素没有被匹配;B.字符串还有右方向括号,但栈中已空,没有字符与其匹配;C.匹配过程中括号类型不同,匹配失败。
class Solution:
def isValid(self, s: str) -> bool:
stack = []
for i in s:
if s == '[':
stack.append(']')
elif s == '(':
stack.append(')')
elif s == '{':
stack.append('}')
elif not stack or stack[-1] != i:
return False
else:
stack.pop()
return True if not stack else False
四、1047. 删除字符串中的所有相邻重复项
1. 看完代码随想录的想法
(1)对于本题目,遍历字符串中每个字符,遇到相邻元素相同则消除,会存在消除后前面的旧元素又可以与新元素进行消除,所以沿用上一题目的思路,既需要匹配又需要消除的题目,可以使用栈来解决。
(2)首先初始化定义一个栈,然后遍历整个字符串中字符,如果栈不为空并且当前遍历的字符与栈顶字符相等,那么就将栈顶字符弹出,实现了遇到相同字符则消除的要求;如果栈为空或者栈中已有字符与当前字符不相等,那么将该字符加入栈;最后将栈中字符进行拼接并返回,就得到我们所需的删除字符串中所有相邻重复项。
class Solution:
def removeDuplicates(self, s: str) -> str:
stack = []
for i in s:
if stack and stack[-1] == i:
stack.pop()
else:
stack.append(i)
return "".join(stack)