#20 有效的括号
由于栈结构的特殊性,非常适合做对称匹配类的题目。
首先要弄清楚,字符串里的括号不匹配有几种情况。
一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。
建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。
先来分析一下 这里有三种不匹配的情况,
-
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
-
第二种情况,括号没有多余,但是 括号的类型没有匹配上。
-
第三种情况,字符串里右方向的括号多余了,所以不匹配。
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。
分析完之后,代码其实就比较好写了,
但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!
# 方法一,仅使用栈,更省空间
class Solution:
def isValid(self, s: str) -> bool:
stack = []
for item in s:
if item == '(':
stack.append(')')
elif item == '[':
stack.append(']')
elif item == '{':
stack.append('}')
elif not stack or stack[-1] != item:
return False
else:
stack.pop()
return True if not stack else False
stack [-1] != item 就是杜绝 {[ }] 的情况,top()出来的/栈里面的必须第一个符合左括号
#1047. 删除字符串中的所有相邻重复项
class Solution:
def removeDuplicates(self, s: str) -> str:
res = list()
for item in s:
if res and res[-1] == item:
res.pop()
else:
res.append(item)
return "".join(res)
看懂了,慢慢想思路还是能写出来
# LeetCode:150. 逆波兰表达式求值
from operator import add,sub, mul
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
op_map = {'+':add, '-':sub,'*':mul,'/':lambda x,y:int(x/y)}
stack = []
for key in tokens:
if key not in {'+','-','*','/'}:
stack.append(int(key))
else:
num2 = stack.pop()
num1 = stack.pop()
stack.append(op_map[key](num1,num2))
return stack.pop()
栈操作步骤
- 表达式:
["2", "3", "+"]
- 栈操作:
- 遇到
2
,压入栈中,栈变为[2]
- 遇到
3
,压入栈中,栈变为[2, 3]
- 遇到
+
,弹出两个操作数,先弹出的是3
,再弹出的是2
- 执行
2 + 3
,结果5
压入栈中,栈变为[5]
- 遇到
为什么先弹出的是 op2
在执行操作时,逆波兰表达式的运算符应用于最后两个弹出的操作数,因此需要按如下顺序进行:
- 先弹出
op2
:这是最后压入栈的操作数(在上例中是3
)。 - 再弹出
op1
:这是倒数第二个压入栈的操作数(在上例中是2
)。
这种顺序保证了运算的正确性,即操作符作用于正确的操作数顺序(op1 操作符 op2
)