☆打卡算法☆LeetCode 150. 逆波兰表达式求值 算法解析
推荐阅读
大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。
一、题目
1、算法题目
“根据逆波兰表达式求表达式的值。”
题目链接:
来源:力扣(LeetCode)
链接: 150. 逆波兰表达式求值 - 力扣(LeetCode)
2、题目描述
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
注意 两个整数之间的除法只保留整数部分。
可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: tokens = ["2","1","+","3","*"]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入: tokens = ["4","13","5","/","+"]
输出: 6
解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
二、解题
1、思路分析
首先来了解一下什么是逆波兰表达式。
逆波兰表达式是波兰的逻辑学家卢卡西维兹提出,逆波兰表达式的特点是:没有括号,运算符总是放在和它相关的操作数之后,所以,逆波兰表达式也被称为后缀表达式。
根据 逆波兰表示法,求表达式的值,可以使用栈存储操作数,从左到右遍历逆波兰表达式:
- 遇到操作数,将操作数入栈
- 遇到运算符,将两个操作数出栈,先出栈的右操作数,后出栈的是左操作数,使用运算符对两个操作数进行运算
- 将运算后的得到的新操作数入栈
整个逆波兰表达式遍历之后,栈内只有一个元素,也就是逆波兰表达式的值。
2、代码实现
代码参考:
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList<Integer>();
int n = tokens.length;
for (int i = 0; i < n; i++) {
String token = tokens[i];
if (isNumber(token)) {
stack.push(Integer.parseInt(token));
} else {
int num2 = stack.pop();
int num1 = stack.pop();
switch (token) {
case "+":
stack.push(num1 + num2);
break;
case "-":
stack.push(num1 - num2);
break;
case "*":
stack.push(num1 * num2);
break;
case "/":
stack.push(num1 / num2);
break;
default:
}
}
}
return stack.pop();
}
public boolean isNumber(String token) {
return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
}
}
3、时间复杂度
时间复杂度:O(n)
其中n是数组tokens的长度,需要遍历数组一次。
空间复杂度:O(n)
其中n是数组tokens的长度,栈内元素个数不会超过逆波兰表达式的长度。
三、总结
对于这道题来说,还可以使用递归来解。
因为对于逆波兰表达式来说,序列的最后一个符号一定是最先得到计算的,而一旦有符号,就至少需要两个以上的操作数。
用一个变量,记录表达式遍历的位置,遇到操作数可以返回,遇到符号则再递归地计算两个操作数,然后根据不同的符号进行对应的计算返回即可。
- 点赞
- 收藏
- 关注作者
评论(0)