用stack
遇到左边的就存进去,右边的pop出来,看等不等于,最后len == 0
在stack内直接存入对应的右边的符号
def isValid(self, s: str) -> bool:
if s is None or len(s) == 0:
return True
if len(s) == 1:
return False
stack = []
for sign in s:
if sign == "(":
stack.append(")")
elif sign == "{":
stack.append("}")
elif sign =="[":
stack.append("]")
else:
if len(stack) == 0 or stack.pop() != sign:
return False
return len(stack) == 0
栈的应用:
cd a/b/c/../../
不匹配的情况:
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
- 已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况,括号没有多余,但是 括号的类型没有匹配上。
- 遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况,字符串里右方向的括号多余了,所以不匹配。
- 遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
我拿到题的时候完全没想到要用stack,还在想着遍历整个string比较,stack明显更加简单,知道要用stack以后就好写很多
栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素,然后再去做对应的消除操作
def removeDuplicates(self, s: str) -> str:
stack = []
for char in s:
if len(stack) == 0:
stack.append(char)
else:
prev = stack.pop()
if prev != char:
stack.append(prev)
stack.append(char)
return "".join(stack)
如何想到栈:
栈可以调用上一个参数,所以如果要和前面的进行比较的话,可以想想能不能用stack
游戏开发可能使用栈结构,编程语言的一些功能实现也会使用栈结构,实现函数递归调用就需要栈,但不是每种编程语言都支持递归,例如:递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因
相信大家应该遇到过一种错误就是栈溢出,系统输出的异常是Segmentation fault
(当然不是所有的Segmentation fault
都是栈溢出导致的) ,如果你使用了递归,就要想一想是不是无限递归了,那么系统调用栈就会溢出。
而且在企业项目开发中,尽量不要使用递归!在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)
遇到数字就加入stack,遇到符号就pop出来俩个计算。注意的是,一直debug有问题,除法那里要int(a/b),不能直接(a//b)
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for s in tokens:
if s == "+":
stack.append(stack.pop() + stack.pop())
elif s == "*":
stack.append(stack.pop() * stack.pop())
elif s == "/":
b = stack.pop()
a = stack.pop()
stack.append(int(a / b))
elif s == "-":
b = stack.pop()
a = stack.pop()
stack.append(a - b)
else:
stack.append(int(s))
print("stack", stack)
return stack.pop()
一些比较经典的题用stack就不用多说,有些题如果看到要比较上一个参数的话可以想想是否能用stack做