继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

LeetCode 150:逆波兰表达式求值 Evaluate Reverse Polish Notation

爱写Bug
关注TA
已关注
手记 88
粉丝 17
获赞 43

题目:

根据逆波兰表示法,求表达式的值。

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

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +, -, *, /. Each operand may be an integer or another expression.

说明:

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

Note:

  • Division between two integers should truncate toward zero.
  • The given RPN expression is always valid. That means the expression would always evaluate to a result and there won’t be any divide by zero operation.

示例 1:

输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: ((2 + 1) * 3) = 9

示例 2:

输入: ["4", "13", "5", "/", "+"]
输出: 6
解释: (4 + (13 / 5)) = 6

示例 3:

输入: ["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

扩展:

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:

a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a,1,3,+,=

从上面的例子可以看出:
(1) 在两种表示中,运算对象出现的顺序相同;
(2) 在后缀表示中,运算符按实际计算顺序从左到右排列,且每一运算符总是跟在其运算对象之后。

这种表达式很反人类,但是对计算机很友好,因为计算机运算是利用栈数据结构。

解题思路:

可以看出逆波兰表达式中的每一个运算符属于该运算符前的两个数字间的运算。如:

如波兰表达式:1,2,+
则加号前两个数字为1,2。其运算符就是加号:1+2
得出结果:1+2=3

如波兰表达式:1,2,3,+,-
则加号前两个数字为2,3。其运算符就是加号:2+3
得出结果2+3=5,则波兰表达式变为:1,5,-
减号前两个数字为1,5,其运算符就是减号:1-5
得出结果1-5=-4

由上面的的例子思路就很清晰了,直接用指针遍历表达式,遇到数字就入栈,遇到运算符就弹出两个数字,把他们运算之后得出结果,再作为独立数字入栈。最后栈内只剩一个元素 即表达式运算结果。也可以用递归

Java:

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for (String t : tokens) {
            if (t.equals("+")) {
                stack.push(stack.pop() + stack.pop());
            } else if (t.equals("-")) {
                int tmp = stack.pop();
                stack.push(stack.pop() - tmp);
            } else if (t.equals("*")) {
                int tmp = stack.pop();
                stack.push(stack.pop() * tmp);
            } else if (t.equals("/")) {
                int tmp = stack.pop();
                stack.push(stack.pop() / tmp);
            } else {
                stack.push(Integer.parseInt(t));
            }
        }
        return stack.pop();
    }
}

Python:

python也可以用数组代替栈完成上述方法解答本题。这里用另一个函数 eval() 代替上述四个 if 判断:

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for t in tokens:
            if t in '+-*/':
                tmp = stack.pop()
                stack.append(int(eval('stack.pop()' + t + 'tmp')))
            else:
                stack.append(int(t))
        return stack.pop()

eval() 函数可以执行传入参数 字符串语句。

eval('print("hhhhh")') 会执行参数字符串打印出: hhhhh

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP