代码随想录|Day10|栈与队列02|20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

20. 有效的括号

确保每个左括号都能找到一个相对应的右括号,并且括号的顺序是正确的。

当遍历到左括号,就向栈压入对应右括号,

当遍历到右括号,就从栈顶弹出对应右括号,

如果栈顶右括号和遍历的右括号不同,则说明为无效括号,

如果遍历结束前,栈为空,则说明为无效括号。

class Solution:
    def isValid(self, s: str) -> bool:

        stack = []

        for bracket in s:
            # 若遇到左括号,则将对应右括号压入栈
            if bracket == '(':
                stack.append(')')
            elif bracket == '{':
                stack.append('}')
            elif bracket == '[':
                stack.append(']')
            # 若遇到右括号,则将栈顶右括号推出
            # 若stack为空,或者与栈顶右括号不匹配,则括号无效
            elif not stack or stack[-1] != bracket:
                return False
            else:
                stack.pop()
        # 当字符串遍历完成,stack应该为空
        return not stack

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

本题与上一题使用相同的思路,借助栈可以实现看似难以处理的操作。

class Solution:
    def removeDuplicates(self, s: str) -> str:

        stack = []

        for char in s:
            # 如果 stack 不为空,且栈顶元素和遍历元素相同,则弹出栈顶元素
            if stack and stack[-1] == char:
                stack.pop()
            # 否则,遍历元素入栈
            else:
                stack.append(char)
        
        return ''.join(stack)

150. 逆波兰表达式求值 

什么是逆波兰表达式?这里引用代码随想录中的解释:

"

我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。

例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算符,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!

那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈来顺序处理,不需要考虑优先级了。也不用回退了, 所以后缀表达式对计算机来说是非常友好的。

可以说本题不仅仅是一道好题,也展现出计算机的思考方式。

在1970年代和1980年代,惠普在其所有台式和手持式计算器中都使用了RPN(后缀表达式),直到2020年代仍在某些模型中使用了RPN。

参考维基百科如下:

During the 1970s and 1980s, Hewlett-Packard used RPN in all of their desktop and hand-held calculators, and continued to use it in some models into the 2020s.

"

如一下动画所示,如果遇到数字,直接入栈,如果遇到运算符,则取出栈顶2个数字进行运算。特别注意,最先出栈的数字是右操作数。

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:

        stack = []

        for token in tokens:
            # 如果遇到运算符,则需要弹出栈顶两个数字以进行运算
            if token in {'+', '-', '*', '/'}:
                # 需要注意的是,先弹出的数字是右操作数
                right = stack.pop()
                left = stack.pop()

                if token == '+':
                    stack.append(left + right)
                elif token == '-':
                    stack.append(left - right)
                elif token == '*':
                    stack.append(left * right)
                elif token == '/':
                    stack.append(int(left / right))
            # 如果遇到数字,则直接入栈
            else:
                stack.append(int(token))

        return stack.pop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值