加载中...
150-逆波兰表达式求值(Evaluate Reverse Polish Notation)
发表于:2021-12-03 | 分类: 中等
字数统计: 607 | 阅读时长: 3分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/evaluate-reverse-polish-notation

英文原文

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

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

Note that division between two integers should truncate toward zero.

It is guaranteed that the given RPN expression is always valid. That means the expression would always evaluate to a result, and there will not be any division by zero operation.

 

Example 1:

Input: tokens = ["2","1","+","3","*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Example 2:

Input: tokens = ["4","13","5","/","+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6

Example 3:

Input: tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
Output: 22
Explanation: ((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

 

Constraints:

  • 1 <= tokens.length <= 104
  • tokens[i] is either an operator: "+", "-", "*", or "/", or an integer in the range [-200, 200].

中文题目

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

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

 

说明:

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

 

示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入: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 <= tokens.length <= 104
  • tokens[i] 要么是一个算符("+""-""*""/"),要么是一个在范围 [-200, 200] 内的整数

 

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * )

逆波兰表达式主要有以下两个优点:

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

通过代码

高赞题解

image.png


均击败99%,都很容易理解!


其他Java相关优化操作:

  1. 数组最大长度为tokens.length / 2 + 1

  2. switch代替if-else,效率优化

  3. Integer.parseInt代替Integer.valueOf,减少自动拆箱装箱操作

附两种方法:

纯数组模拟栈实现(推荐):


class Solution {

	//纯数组模拟栈实现(推荐)   3 ms	36 MB

	public static int evalRPN(String[] tokens) {

		int[] numStack = new int[tokens.length / 2 + 1];

		int index = 0;

		for (String s : tokens) {

			switch (s) {

			case "+":

				numStack[index - 2] += numStack[--index];

				break;

			case "-":

				numStack[index - 2] -= numStack[--index];

				break;

			case "*":

				numStack[index - 2] *= numStack[--index];

				break;

			case "/":

				numStack[index - 2] /= numStack[--index];

				break;

			default:

				// numStack[index++] = Integer.valueOf(s);

				//valueOf改为parseInt,减少自动拆箱装箱操作

				numStack[index++] = Integer.parseInt(s);

				break;

			}

		}

		return numStack[0];

	}

}

栈实现:


class Solution {

	// 栈实现   8 ms	36.7 MB	

	public static int evalRPN(String[] tokens) {

		Stack<Integer> numStack = new Stack<>();

		Integer op1, op2;

		for (String s : tokens) {

			switch (s) {

			case "+":

				op2 = numStack.pop();

				op1 = numStack.pop();

				numStack.push(op1 + op2);

				break;

			case "-":

				op2 = numStack.pop();

				op1 = numStack.pop();

				numStack.push(op1 - op2);

				break;

			case "*":

				op2 = numStack.pop();

				op1 = numStack.pop();

				numStack.push(op1 * op2);

				break;

			case "/":

				op2 = numStack.pop();

				op1 = numStack.pop();

				numStack.push(op1 / op2);

				break;

			default:

				numStack.push(Integer.valueOf(s));

				break;

			}

		}

		return numStack.pop();

	}

}

统计信息

通过次数 提交次数 AC比率
142899 267385 53.4%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言

相似题目

题目 难度
基本计算器 困难
给表达式添加运算符 困难
上一篇:
149-直线上最多的点数(Max Points on a Line)
下一篇:
151-翻转字符串里的单词(Reverse Words in a String)
本文目录
本文目录