mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 08:50:15 +08:00
update 0150.逆波兰表达式求值: 更新js代码
This commit is contained in:
@ -51,7 +51,7 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
逆波兰表达式:是一种后缀表达式,所谓后缀就是指算符写在后面。
|
逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。
|
||||||
|
|
||||||
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
|
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
|
||||||
|
|
||||||
@ -61,11 +61,11 @@
|
|||||||
|
|
||||||
* 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
|
* 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
|
||||||
|
|
||||||
* 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
|
* 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
|
||||||
|
|
||||||
# 思路
|
# 思路
|
||||||
|
|
||||||
《代码随想录》算法视频公开课:[栈的最后表演! | LeetCode:150. 逆波兰表达式求值](https://www.bilibili.com/video/BV1kd4y1o7on),相信结合视频在看本篇题解,更有助于大家对本题的理解。
|
《代码随想录》算法视频公开课:[栈的最后表演! | LeetCode:150. 逆波兰表达式求值](https://www.bilibili.com/video/BV1kd4y1o7on),相信结合视频再看本篇题解,更有助于大家对本题的理解。
|
||||||
|
|
||||||
在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)提到了 递归就是用栈来实现的。
|
在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)提到了 递归就是用栈来实现的。
|
||||||
|
|
||||||
@ -73,7 +73,7 @@
|
|||||||
|
|
||||||
那么来看一下本题,**其实逆波兰表达式相当于是二叉树中的后序遍历**。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。
|
那么来看一下本题,**其实逆波兰表达式相当于是二叉树中的后序遍历**。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。
|
||||||
|
|
||||||
但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后续遍历的方式把二叉树序列化了,就可以了。
|
但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后序遍历的方式把二叉树序列化了,就可以了。
|
||||||
|
|
||||||
在进一步看,本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么**这岂不就是一个相邻字符串消除的过程,和[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)中的对对碰游戏是不是就非常像了。**
|
在进一步看,本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么**这岂不就是一个相邻字符串消除的过程,和[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)中的对对碰游戏是不是就非常像了。**
|
||||||
|
|
||||||
@ -118,9 +118,9 @@ public:
|
|||||||
|
|
||||||
我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。
|
我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。
|
||||||
|
|
||||||
例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算法,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!
|
例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算符,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!
|
||||||
|
|
||||||
那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈里顺序处理,不需要考虑优先级了。也不用回退了, **所以后缀表达式对计算机来说是非常友好的。**
|
那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈来顺序处理,不需要考虑优先级了。也不用回退了, **所以后缀表达式对计算机来说是非常友好的。**
|
||||||
|
|
||||||
可以说本题不仅仅是一道好题,也展现出计算机的思考方式。
|
可以说本题不仅仅是一道好题,也展现出计算机的思考方式。
|
||||||
|
|
||||||
@ -161,6 +161,24 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
python3
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def evalRPN(self, tokens: List[str]) -> int:
|
||||||
|
stack = []
|
||||||
|
for item in tokens:
|
||||||
|
if item not in {"+", "-", "*", "/"}:
|
||||||
|
stack.append(item)
|
||||||
|
else:
|
||||||
|
first_num, second_num = stack.pop(), stack.pop()
|
||||||
|
stack.append(
|
||||||
|
int(eval(f'{second_num} {item} {first_num}')) # 第一个出来的在运算符后面
|
||||||
|
)
|
||||||
|
return int(stack.pop()) # 如果一开始只有一个数,那么会是字符串形式的
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
```Go
|
```Go
|
||||||
func evalRPN(tokens []string) int {
|
func evalRPN(tokens []string) int {
|
||||||
@ -169,7 +187,7 @@ func evalRPN(tokens []string) int {
|
|||||||
val, err := strconv.Atoi(token)
|
val, err := strconv.Atoi(token)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
stack = append(stack, val)
|
stack = append(stack, val)
|
||||||
} else {
|
} else { // 如果err不为nil说明不是数字
|
||||||
num1, num2 := stack[len(stack)-2], stack[(len(stack))-1]
|
num1, num2 := stack[len(stack)-2], stack[(len(stack))-1]
|
||||||
stack = stack[:len(stack)-2]
|
stack = stack[:len(stack)-2]
|
||||||
switch token {
|
switch token {
|
||||||
@ -191,27 +209,31 @@ func evalRPN(tokens []string) int {
|
|||||||
javaScript:
|
javaScript:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
var evalRPN = function (tokens) {
|
||||||
/**
|
|
||||||
* @param {string[]} tokens
|
|
||||||
* @return {number}
|
|
||||||
*/
|
|
||||||
var evalRPN = function(tokens) {
|
|
||||||
const s = new Map([
|
|
||||||
["+", (a, b) => a * 1 + b * 1],
|
|
||||||
["-", (a, b) => b - a],
|
|
||||||
["*", (a, b) => b * a],
|
|
||||||
["/", (a, b) => (b / a) | 0]
|
|
||||||
]);
|
|
||||||
const stack = [];
|
const stack = [];
|
||||||
for (const i of tokens) {
|
for (const token of tokens) {
|
||||||
if(!s.has(i)) {
|
if (isNaN(Number(token))) { // 非数字
|
||||||
stack.push(i);
|
const n2 = stack.pop(); // 出栈两个数字
|
||||||
continue;
|
const n1 = stack.pop();
|
||||||
|
switch (token) { // 判断运算符类型,算出新数入栈
|
||||||
|
case "+":
|
||||||
|
stack.push(n1 + n2);
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
stack.push(n1 - n2);
|
||||||
|
break;
|
||||||
|
case "*":
|
||||||
|
stack.push(n1 * n2);
|
||||||
|
break;
|
||||||
|
case "/":
|
||||||
|
stack.push(n1 / n2 | 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else { // 数字
|
||||||
|
stack.push(Number(token));
|
||||||
}
|
}
|
||||||
stack.push(s.get(i)(stack.pop(),stack.pop()))
|
|
||||||
}
|
}
|
||||||
return stack.pop();
|
return stack[0]; // 因没有遇到运算符而待在栈中的结果
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -280,24 +302,6 @@ function evalRPN(tokens: string[]): number {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
python3
|
|
||||||
|
|
||||||
```python
|
|
||||||
class Solution:
|
|
||||||
def evalRPN(self, tokens: List[str]) -> int:
|
|
||||||
stack = []
|
|
||||||
for item in tokens:
|
|
||||||
if item not in {"+", "-", "*", "/"}:
|
|
||||||
stack.append(item)
|
|
||||||
else:
|
|
||||||
first_num, second_num = stack.pop(), stack.pop()
|
|
||||||
stack.append(
|
|
||||||
int(eval(f'{second_num} {item} {first_num}')) # 第一个出来的在运算符后面
|
|
||||||
)
|
|
||||||
return int(stack.pop()) # 如果一开始只有一个数,那么会是字符串形式的
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
```Swift
|
```Swift
|
||||||
func evalRPN(_ tokens: [String]) -> Int {
|
func evalRPN(_ tokens: [String]) -> Int {
|
||||||
|
Reference in New Issue
Block a user