20. 有效的括号
1.题目
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
20. 有效的括号
2.前记
记得第一次遇见这个题是我第一次笔试的时候,当时觉得这个题可难了,现在听卡哥一讲,用栈来做,思路一下就打开了,而且这个专题虽然是一刷,但是基本上思路和答案一致,不过有一点就是我写的比较慢,审题不仔细!
3.实现
class Solution:
def isValid(self, s: str) -> bool:
# 栈适合做对称匹配的问题,想想原因!
# 如果用队列只能做到有相同数量的括号,但不能保证匹配的上
stack = []
for u in s:
if u == '(' or u == '[' or u == '{':
stack.append(u)
elif u == ')':
if not stack or stack.pop() != '(':
return False
elif u == ']':
if not stack or stack.pop() != '[':
return False
elif u == '}':
if not stack or stack.pop() != '{':
return False
if not stack:
return True
else:
return False
4.讲解
总结:
栈结构的特殊性,非常适合做对称匹配类的题目
1047. 删除字符串中的所有相邻重复项
1.题目
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
1047. 删除字符串中的所有相邻重复项
2.实现
我居然一开始看错题了,没有看到两个相邻重复这个条件,以为只要相邻重复的就行,细心审题
虽然想到了双指针,但是由于审题审错了,觉得这个思路麻烦就直接用栈做了
class Solution:
def removeDuplicates(self, s: str) -> str:
# 定义i j两个指针,i表示数组该位置要判断是否重复的位置,j=i+1进行判断与i是否相等
# 如相等,移动到不相等将[i, j]这段切片删除,j=i+1
# 避免移动指针,可以把字符放入栈中,将元素与top元素相比
stack = []
i = 0
# for循环也可,居然开始的时候看错题目了
while i < len(s):
if not stack or s[i] != stack[-1]:
stack.append(s[i])
i += 1
elif s[i] == stack[-1]:
a = stack.pop()
i += 1
return "".join(stack)
3.讲解
150. 逆波兰表达式求值
1.题目
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
150. 逆波兰表达式求值
2.实现
竟然又搞不清如何取整 好好学,记一下!
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
# 依次放入栈中,遇到算符,将前两个数pop出来进行运算再放入栈中
stack = []
for u in tokens:
if u.isdigit() or len(u) > 1:
stack.append(int(u))
else:
b = stack.pop()
a = stack.pop()
if u == '+':
stack.append(a + b)
if u == '-':
stack.append(a - b)
if u == '/':
# a/b为浮点数,a//b为向下取整,这里要的是向0取整,可以选择int(a/b)
if a / b > 0:
stack.append(a//b)
else:
stack.append(-(abs(a)//abs(b)))
if u == '*':
stack.append(a * b)
return stack[-1]
3.讲解
总结:
1.递归是通过栈来实现的,利用栈将结果(return)返回上一级
2.栈适合做对称匹配+找到当前值和上一个值的关系