代码随想录第十一天 | 20. 有效的括号 | 1047. 删除字符串中的所有相邻重复项 | 150. 逆波兰表达式求值

20. 有效的括号

Leetcode 20 原题链接
本题要匹配上的括号有三种:( ), { }, [ ]。由于栈结构的特殊性,非常适合做对称匹配类的题目。当我们接受到左括号的时候,我们往栈里加入对应的右括号,当匹配到对应的右括号,就可以直接从栈里弹出这个右括号。因此,栈顶元素会一直变化,匹配完的括号会被排出以方便直接记录的括号可以继续匹配。

不匹配的情况分为三种:

  1. 存在多余左括号,最终栈里的右括号没有匹配完,即不为空。
  2. 存在多余右括号,当遍历到这个多余右括号时,栈顶元素不为此括号,或者此时栈里元素为空,也就没办法抵消。
  3. 不存在多余情况,但是遍历到的右括号,无法和应该抵消的左括号匹配,也就是此时栈顶元素不等于遍历到的右括号。
class Solution:
    def isValid(self, s: str) -> bool:
        stack=[]
        for element in s:
            if element=="(":
                stack.append(")")
            elif element=="[":
                stack.append("]")
            elif element=="{":
                stack.append("}")
            # 记录对应左括号的右括号
            elif stack==[] or stack[-1]!=element:
            # 解决情况2和3
                return False
            else:
                stack.pop()
        return True if not stack else False
        # 解决情况1

字典法思路和栈的思路相似,只是用字典来检索。

# 字典法
class Solution:
    def isValid(self, s: str) -> bool:
        stack=[]
        para={
            "(":")",
            "{":"}",
            "[":"]"
        }
        for i in s:
            if i in para.keys():
                stack.append(para[i])
            elif stack==[] or stack[-1]!=i:
                return False
            else:
                stack.pop()
        return True if not stack else False

1047. 删除字符串中的所有相邻重复项

Leetcode 1047 原题链接
我们依然可以将其看作匹配问题,而匹配问题就可以尝试用栈来模拟解决。当遍历到和栈顶元素不同的元素时,将其输入到栈里;而如果和栈顶元素匹配,说明相邻元素重复,直接以从栈里弹出该栈顶元素的方式作为抵消。

class Solution:
    def removeDuplicates(self, s: str) -> str:
        stack=[]
        for i in s:
            if stack==[] or stack[-1]!=i:
            # 记入不和相邻元素重复的元素
                stack.append(i)
            else:
                stack.pop()
        return "".join(stack)

双指针法可以参考下。本质上slow是操作指针,可以看作slow在记录经历的不重复元素,最后输出[0:slow]的元素。fast是终止指针,当它遍历完所有元素停止,且若存在重复相邻元素,让slow往后退一格,fast继续前进,来看作中间相邻元素被抹除,而fast依旧会指向下一个要检索判定的元素。

class Solution:
    def removeDuplicates(self, s: str) -> str:
        res = list(s)
        slow = fast = 0
        length = len(res)

        while fast < length:
            # 如果一样直接换,不一样会把后面的填在slow的位置
            res[slow] = res[fast]
            # print(res,res[slow],res[fast])
            
            # 如果发现和前一个一样,就退一格指针
            if slow > 0 and res[slow] == res[slow - 1]:
                slow -= 1
            else:
                slow += 1
            fast += 1
            # print(f"slow:",slow)
            # print(f"fast",fast)
            
        return ''.join(res[0: slow])

150. 逆波兰表达式求值

Leetcode 150 原题链接
逆波兰表达式优点:适合用栈操作运算,遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        def calculate(num1:int,num2:int,i:str)->int:
            if i=="+": return num1+num2
            elif i=="-": return num1-num2
            elif i=="*": return num1*num2
            elif i=="/": return int(num1/num2)
            
        stack=[]
        for i in tokens:
            if i not in {"+","-","*","/"}:
                stack.append(int(i))
            else:
                num2=stack.pop() # 先弹出的数字在减法和除法是被减和被除的对象
                num1=stack.pop()
                stack.append(calculate(num1,num2,i))
        return stack.pop()
                

或者用字典,对应的value为运算函数。

from operator import add, sub, mul

class Solution:
    op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
    
    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for token in tokens:
            if token not in {'+', '-', '*', '/'}:
                stack.append(int(token))
            else:
                op2 = stack.pop()
                op1 = stack.pop()
                stack.append(self.op_map[token](op1, op2))  # 第一个出来的在运算符后面
        return stack.pop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值