日野弥生:勉強しよう

LeetCode 150 - 逆波兰表达式求值

发表于2025年02月12日

#数学 #数组 #栈

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。 平常使用的算式则是一种中缀表达式,如: $(1+2)*(3+4)$

该算式的逆波兰表达式写法为: $((12+)(34+)*)$

逆波兰表达式主要有以下两个优点: 1、去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。 2、适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> stk;
        for (int i = 0; i < tokens.size(); i++)
        {
            /* 这里也可以使用char类型,且用std::isdigit(),但是leetcode系统不支持,原因不明 */
            string& token = tokens[i];

            /* 考虑到有负数的情况,所以还是直接排除掉四则运算最简单直接 */
            if (!isOperator(token))
                /* 注意利用std::atoi对字符串转换 */
                stk.push(atoi(token.c_str()));
            else
            {
                int num2 = stk.top();
                stk.pop();
                int num1 = stk.top();
                stk.pop();
                /* 不能写成token */
                switch (token[0]) {
                    case '+':
                        stk.push(num1 + num2);
                        break;
                    case '-':
                        stk.push(num1 - num2);
                        break;
                    case '*':
                        stk.push(num1 * num2);
                        break;
                    case '/':
                        stk.push(num1 / num2);
                        break;
                }
            }
        }
        /* 循环结束后的栈顶的元素就是结果 */
        return stk.top();
    }

    bool isOperator(const string& token) {
        return (token == "+" || token == "-" || token == "*" || token == "/");
    }
};

用python3实现时,可以利用operator库和finally机制

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        # 利用字典存储运算符,operator库里的函数
        op_to_binary_fn = {
            "+": operator.add,
            "-": operator.sub,
            "*": operator.mul,
            # 注意不能调用地板除法,得利用向下取整的除法,这里用lambda实现
            "/": lambda x, y: int(x / y),
        }

        stack = list()
        for token in tokens:
            # 利用抛异常和finally关键字实现字符串到数字的转换,C++没有finally是真难受
            try:
                num = int(token)
            except ValueError:
                num2 = stack.pop()
                num1 = stack.pop()
                num = op_to_binary_fn[token](num1, num2)
            finally:
                stack.append(num)
            
        return stack[0]

フラッシュタブ:LeetCode

题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/

上一篇

LeetCode 346 - 数据流中的移动平均值

下一篇

LeetCode 144 - 二叉树的前序遍历