第一题
Given a string
s
containing just the characters'('
,')'
,'{'
,'}'
,'['
and']'
, determine if the input string is valid.An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Every close bracket has a corresponding open bracket of the same type.
题干很容易理解,做起来的话,也可以用笨办法,给左右括号用数组计数,最后看是否还有没匹配好的数组。做了一下发现考虑不足,因为题干要求Open brackets must be closed in the correct order,这样不能检查order
看了解析,才知道这道题是一道经典的,可以使用栈来解决的问题。以及,在写代码时,提前设想这道题所有会出现的情况,考虑周全再写:
1. 左括号多余,匹配不完全
2. 左右括号没有多余,但是类型存在不一致
3. 右括号多余,匹配不完全。
对应的解决方法:
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以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
第二题
1047. Remove All Adjacent Duplicates In String
You are given a string
s
consisting of lowercase English letters. A duplicate removal consists of choosing two adjacent and equal letters and removing them.We repeatedly make duplicate removals on
s
until we no longer can.Return the final string after all such duplicate removals have been made. It can be proven that the answer is unique.
乍一看,像是while循环结构,一直移除重复项直到移除不了为止。不过说到移除重复项,思路又像上一道题的匹配消除括号,可以用栈来解决。遍历字符串的时候,如果碰到重复项就弹出,最后留在栈里的就是结果。
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)
第三题
150. Evaluate Reverse Polish Notation
You are given an array of strings
tokens
that represents an arithmetic expression in a Reverse Polish Notation.Evaluate the expression. Return an integer that represents the value of the expression.
Note that:
- The valid operators are
'+'
,'-'
,'*'
, and'/'
.- Each operand may be an integer or another expression.
- The division between two integers always truncates toward zero.
- There will not be any division by zero.
- The input represents a valid arithmetic expression in a reverse polish notation.
- The answer and all the intermediate calculations can be represented in a 32-bit integer.
这道题一开始感觉云里雾里,但是把一个算式想象成一个二叉树,我们日常阅读习惯就是中缀表示,这个RPN的后缀表示就是后序遍历二叉树。
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for i in tokens:
if i not in ['+','-','*' ,'/']:
stack.append(i)
else:
first_num = stack.pop()
second_num = stack.pop()
stack.append(int(eval(f'{second_num} {i} {first_num}')))
return int(stack.pop())