剑指 Offer II 036. 后缀表达式

91 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

1. 题目与解析

根据 逆波兰表示法,求该后缀表达式的计算结果。

有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。  

输入:tokens = ["2","1","+","3","*"]

输出:9

解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

输入:tokens = ["4","13","5","/","+"]

输出:6

解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

输入:tokens = ["10","6","9","3","+","-11","","/","","17","+","5","+"]

输出:22

解释: 该算式转化为常见的中缀算术表达式为:

((10 * (6 / ((9 + 3) * -11))) + 17) + 5

= ((10 * (6 / (12 * -11))) + 17) + 5

= ((10 * (6 / -132)) + 17) + 5

= ((10 * 0) + 17) + 5

= (0 + 17) + 5

= 17 + 5

= 22

根据题意,我们能很容易地想到,需要利用栈结构来处理这一问题,对于表达式,有数字和符号两种形式,我们来进行分情况的讨论:

  1. 对于数字,我们可以选择直接将数字压入栈中,以供后续的符号操作;
  2. 对于符号,我们需要从栈中取出临近的两个数字,进行对应的操作,操作完成后,我们还需要注意,此时应该将计算后的结果再次压入栈中,以供下次操作使用;
  3. 所有操作都完成后,我们的栈中会剩下最后的结果,输出返回就是我们需要的答案。

2. 题解

class Solution {
    public int evalRPN(String[] tokens) {
        Set<String> set = new HashSet<>();
        Stack<String>  symbolSta = new Stack<>();
        Stack<Integer> numberSta = new Stack<>();
        int tmpNum = 201;
        set.add("+");
        set.add("-");
        set.add("*");
        set.add("/");

        for (int i = 0; i < tokens.length; i++) {
            String symbol = tokens[i];
            int tmp = 0;
            if (set.contains(symbol)) {
                int sec = numberSta.pop(), fri = numberSta.pop();
                if (symbol.equals("+"))      tmp = fri + sec;
                else if (symbol.equals("-")) tmp = fri - sec;
                else if (symbol.equals("*")) tmp = fri * sec;
                else if (symbol.equals("/")) tmp = fri / sec;
            } else {
                tmp = Integer.valueOf(symbol);
            }
            numberSta.push(tmp);
        }

        return numberSta.pop();
    }
}