给你一个字符串数组
tokens
,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为
'+'
、'-'
、'*'
和'/'
。- 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
示例 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 + *
也可以依据次序计算出正确结果。- 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中
java 代码及解题思路
package com.java.leetcode.stackandqueue;
import java.util.Stack;
/**
* 题目描述:
* 根据 逆波兰表示法,求表达式的值。
*
* 有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
*
* 说明:
*
* 整数除法只保留整数部分。
* 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
*
*
* 示例 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
* ```
*
*
* 逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。
*
* 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
*
* 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
*
* 逆波兰表达式主要有以下两个优点:
*
* * 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
*
* * 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
*/
public class evalRPN150 {
/**
* 根据 题目描述
* 1 2 + 3 4 + * => ( ( 1 2 + ) ( 3 4 + ) * )==>( 1 + 2 ) * ( 3 + 4 )
* 变形为上述公式 不难发现
* 表达式 数字后面跟着 计算符号 为 该域 的计算模块 模块算子之间 计算结果 进行二级结果 重复计算 得到最终结果
* 因此根据此特性 适合使用栈操作:
* 遇到数字 则压栈 遇到运算符则 取出两个栈顶数据 进行计算 结果 压栈
*
* @param tokens
* @return
*/
public int evalRPN(String[] tokens){
// 根据上述思路可以得到以下代码逻辑
Stack<Integer> stack=new Stack<>();
for (String token : tokens) {
//+ , - , * , /
if (token.equals("+")) {
stack.push(stack.pop() + stack.pop());
} else if (token.equals("-")) {
stack.push(-stack.pop() + stack.pop());
} else if (token.equals("*")) {
stack.push(stack.pop() * stack.pop());
} else if (token.equals("/")) {
int t1 = stack.pop();
int t2 = stack.pop();
stack.push(t2 / t1);
} else {
stack.push(Integer.valueOf(token));
}
}
return stack.pop();
}
}