20. 有效的括号
由于栈结构的特殊性,非常适合做对称匹配类的题目。只要能够明确匹配关系,就可以知道什么时候 push,什么时候 pop,可以很好利用栈的 LIFO 的特性。
自己的解法(略笨重)
符合直觉的思路,从后向前在 stack 中存入每个字符,如果存入的是前括号,则 pop 栈中的最后一个元素并检查是否是对应的后括号,不匹配则 return False。
最后如果 stack 不为空,则 return False,反之return True。
class Solution:
def isValid(self, s: str) -> bool:
str_stack = list(s)
bracket_stack = []
while (len(str_stack) > 0):
curr_bracket = str_stack.pop()
if curr_bracket in [')', ']', '}']:
bracket_stack.append(curr_bracket)
else:
if len(bracket_stack) == 0:
return False
else:
if curr_bracket == '(' and bracket_stack.pop() != ')':
return False
if curr_bracket == '[' and bracket_stack.pop() != ']':
return False
if curr_bracket == '{' and bracket_stack.pop() != '}':
return False
return len(bracket_stack) == 0
标准的栈解法
更加简洁一些的解法,从头开始遇到前括号则在 stack 中存入对应的后括号,遇到后括号则比较当前 stack 的 pop 元素是否匹配。
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
class Solution:
def isValid(self, s: str) -> bool:
bracket_stack = []
for letter in s:
if letter == '(':
bracket_stack.append(')')
elif letter == '[':
bracket_stack.append(']')
elif letter == '{':
bracket_stack.append('}')
elif len(bracket_stack) == 0: # the read letter must be a close bracket
return False
elif bracket_stack[-1] != letter:
return False
else:
bracket_stack.pop()
return len(bracket_stack) == 0
1047. 删除字符串中的所有相邻重复项
和上一题几乎一样,只是这次是匹配相邻元素,更加符合栈的特性。
class Solution:
def removeDuplicates(self, s: str) -> str:
stack = []
for letter in s:
if len(stack) > 0:
top_letter = stack.pop()
if top_letter != letter:
stack.append(top_letter)
stack.append(letter)
else:
stack.append(letter)
return "".join(stack)
150. 逆波兰表达式求值
逆波兰表达式是一种后缀表达式,即 operator 写在 operand 的后面。
例如:10 6 9 3 + -11 * / * 17 + 5 + = (10 * 6 / [(9+3) * (-11))]) + 17 + 5
逆波兰表达式很好的展现了计算机的计算方式,这和人类的计算思路是不一样的。
由于逆波兰表达式严格遵循从左到右的计算顺序,不需要括号以及优先级判断,所以非常适合使用栈来进行运算.
注意的是,在 / 的 case 中,int(operand2 / operand1)
的计算方式是“The division between two integers always truncates toward zero”。在结果为 negative float 的时候,是向0取整,和 // 的向下取整是不同的。
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for s in tokens:
if s.isdigit() or (s[0] == '-' and len(s) > 1):
stack.append(int(s))
else:
operand1 = stack.pop()
operand2 = stack.pop()
if s == '+':
stack.append(operand2 + operand1)
if s == '-':
stack.append(operand2 - operand1)
if s == '*':
stack.append(operand2 * operand1)
if s == '/':
stack.append(int(operand2 / operand1))
return stack[0]