有效的括号
题目链接leetcode 20.
题目描述:
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
每识别一个括号,我们就需要对比最新添加的一个括号,这种考虑最新的,最近的一个元素可以考虑使用栈。如果我们用栈,就需要考虑入栈的是什么元素,以及什么情况下出栈。
第一种方法是将左括号作为入栈元素,若是遇到右括号,则判断栈顶的左括号是否与之匹配。
第二种则是将右括号入栈,但是注意入的右括号不是遍历得到的右括号,而是遍历的左括号对应的右括号,也即此栈表示正确配对所需要的右括号。
在左右括号正确匹配后,我们就不再需要考虑这对括号,所以就可以将栈顶的括号弹出,最后在遍历完所有括号后,判断栈是否为空,为空说明左右括号数目匹配,输出正确;否则尾错误。
Python 代码
# 方法 1
class Solution:
def isValid(self, s: str) -> bool:
stack = []
left = ["(","{","["]
right = [")","}","]"]
for i in s:
if i in left:
stack.append(i)
else:
if stack == []:
return False
else:
ind = right.index(i)
if stack[-1] != left[ind]:
return False
stack.pop()
return stack == []
# 方法 2
class Solution:
def isValid(self, s: str) -> bool:
stack = []
left = ["(","{","["]
right = [")","}","]"]
for i in s:
if i in left:
ind = left.index(i)
stack.append(right[ind])
elif not stack or stack[-1] != i :
return False
else:
stack.pop()
return stack == []
删除字符串中的所有相邻重复项
题目链接 leetcode 1047.
题目描述:
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
题目里强调了删除两个,也就是说如果由三个重复的字符也是仍然只删除两个。涉及到最近的匹配,我们仍然可以考虑使用栈。
将元素先和栈顶比较:相同则pop,否则加入栈。在比较时注意栈是否为空,为空则直接入栈。
Python 代码
class Solution:
def removeDuplicates(self, s: str) -> str:
stack = []
for i in s:
if not stack or stack[-1]!=i:
stack.append(i)
else:
stack.pop()
return "".join(stack)
逆波兰表达式求值
题目链接 leetcode 150.
题目描述:
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
注意 两个整数之间的除法只保留整数部分。
逆波兰表达式是一种后缀表达式,将运算符放在后面。当遇到运算符时,找到最后面两个数字进行运算,一样是涉及到最近的,考虑栈。我们需要弹出两个数字,然后进行运算并将运算数值压入栈中。 注意首先弹出的是运算符后面的数字。
Python 代码
Python 中 int() 可以取整数部分,// 是向下取整。
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
op = ["+","-","*","/"]
stack = []
for i in tokens:
if i not in op:
stack.append(i)
else:
b = int(stack.pop())
a = int(stack.pop())
if i == "+":
stack.append(a+b)
elif i == "-":
stack.append(a-b)
elif i == "*":
stack.append(a*b)
else:
stack.append(int(a/b))
return int(stack.pop())