文章目录

  • 1.问题描述
  • 2.难度等级
  • 3.热门指数
  • 4.解题思路
  • 5.实现示例
    • 5.1 C++
    • 5.2 Golang
  • 参考文献

1.问题描述

逆波兰表达式也叫后缀表达式。

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

注意,两个整数之间的除法只保留整数部分。

示例 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

2.难度等级

easy。

3.热门指数

★★★★☆

出题公司:腾讯,拼多多。

4.解题思路

逆波兰表达式由波兰的逻辑学家卢卡西维兹提出。逆波兰表达式的特点是:没有括号,运算符总是放在和它相关的操作数之后。因此,逆波兰表达式也称后缀表达式。

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

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

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

通过观察逆波兰表达式的求值过程可以发现,整个过程就是操作数入栈出栈的过程。因此我们可以使用栈来完成逆波兰表达式的求值。

从左到右遍历逆波兰表达式,进行如下操作:

  • 如果遇到操作数,则将操作数入栈;
  • 如果遇到运算符,则将两个操作数出栈,其中先出栈的是右操作数,后出栈的是左操作数,使用运算符对两个操作数进行运算,将运算得到的新操作数入栈。

整个逆波兰表达式遍历完毕之后,栈内只有一个元素,该元素即为逆波兰表达式的值。

复杂度分析:

时间复杂度:O(n)。遍历完表达式即可完成运算。

空间复杂度:O(n)。假设表达式长度为 n,那么操作数的个数为 ceil(n/2) 向上取整。极端情况下所有操作数全部入栈后才开始运算,所以空间复杂度为 O(n)。

5.实现示例

5.1 C++

// evalRPN 逆波兰表达式求值。
int evalRPN(vector<string> &tokens) {stack<int> stk;for (auto s : tokens) {if (s == "+" || s == "-" || s == "*" || s == "/") {int64_t num2 = stk.top();stk.pop();int64_t num1 = stk.top();stk.pop();if (s == "+")stk.push(num1 + num2);if (s == "-")stk.push(num1 - num2);if (s == "*")stk.push(num1 * num2);if (s == "/")stk.push(num1 / num2);continue;}stk.push(stol(s));}return stk.top();
}

验证代码:

#include <iostream>
#include <stack>
#include <vector>
#include <string>
using namespace std;int main() {auto tokens = vector<string>{"2","1","+","3","*"};cout << evalRPN(tokens) << endl;tokens = vector<string>{"4","13","5","/","+"};cout << evalRPN(tokens) << endl;tokens = vector<string>{"10","6","9","3","+","-11","*","/","*","17","+","5","+"};cout << evalRPN(tokens) << endl;
}

运行输出:

9
6
22

5.2 Golang

// evalRPN 逆波兰表达式求值。
func evalRPN(tokens []string) int {var stack []intfor _, s := range tokens{switch s {case "+", "-", "*", "/":num1, num2 := stack[len(stack)-2], stack[len(stack)-1]stack = stack[:len(stack)-2]switch s {case "-":stack = append(stack, num1 - num2)case "+":stack = append(stack, num1 + num2)case "*":stack = append(stack, num1 * num2)case "/":stack = append(stack, num1 / num2)}default:num, _ := strconv.Atoi(s)stack = append(stack, num)}}return stack[0]
}

验证代码:

package mainimport ("fmt""strconv"
}func main() {fmt.Println(evalRPN([]string{"2","1","+","3","*"}))fmt.Println(evalRPN([]string{"4","13","5","/","+"}))   fmt.Println(evalRPN([]string{"10","6","9","3","+","-11","*","/","*","17","+","5","+"}))
}

运行输出:

9
6
22

参考文献

150. 逆波兰表达式求值 - leetcode

逆波兰表达式求值(leetcode 150)相关推荐

  1. 算法训练Day11|LeetCode 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

    题目链接:20. 有效的括号 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false 第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字 ...

  2. LetCode: 150. 逆波兰表达式求值

    提示 LintCode中的相关算法题实现代码,可以在我的GithHub中下载. 题目需求 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另 ...

  3. Suzy找到实习了吗Day 11 |栈与队列中途 20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

    Day 11 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值 20. 有效的括号 注意栈不是一个数据结构,需要自己用list实现栈的逻辑 class Solu ...

  4. 算法训练第十一天|力扣20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

    20. 有效的括号 题目链接:有效的括号 参考:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B ...

  5. (补)算法训练Day13 | LeetCode150. 逆波兰表达式求值(栈应用);LeetCode239. 滑动窗口最大值(单调队列);LeetCode347. 前K个高频元素(小顶堆,优先级队列)

    目录 LeetCode150. 逆波兰表达式求值 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 LeetCode239. 滑动窗口最大值 1. 思路 2. 代码实现 3. 复杂度分析 4. ...

  6. 代码随想录第11天 | LeetCode20. 有效的括号、LeetCode1047. 删除字符串中的所有相邻重复项、LeetCode150. 逆波兰表达式求值

    day11 | LeetCode20. 有效的括号.LeetCode1047. 删除字符串中的所有相邻重复项.LeetCode150. 逆波兰表达式求值 文章目录 day11 | LeetCode20 ...

  7. JavaScript逆波兰表达式求值

    逆波兰表达式简介 逆波兰表达式又叫做后缀表达式.逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasiewicz)于1929年首先提出的一种表达式的表示方法 .后来,人们就把用这种表示法写出的表 ...

  8. 【Java版oj】逆波兰表达式求值

    目录 一.原题再现 二.问题分析 三.完整代码 一.原题再现 150. 逆波兰表达式求值 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除 ...

  9. 复习栈和队列,详解最小栈,栈的弹出压入序列,逆波兰表达式求值

    栈和队列的概念 栈:吃进去吐出来 对列:吃进去拉出来 数据结构中的栈和内存中的区别 数据结构中的栈具有后进先出的特性,而内存中的栈是一个内存空间,只不过这个内存空间具与数据结构的栈具有相同的特性. 栈 ...

最新文章

  1. GO语言变量和常量、语言控制语句流程
  2. 傅里叶变换:周期、非周期 与连续、离散
  3. python开发板比较_再不学点Python,咱真老了--Adafruit Metro M0 Express开发板评测
  4. 中年程序员,有哪些关于保护身体健康的知识分享给同行的你?
  5. python字典里存字符_Python字典和字符串的学习
  6. 【数据结构总结】第四章:串、数组和广义表(线性结构)
  7. 前端学习(2446):总页码的处理
  8. Android 进程间通信——Service、Messenger
  9. python3.0与2.x之间的区别
  10. springboot转发http请求_Spring Boot2 系列教程(八)Spring Boot 中配置 Https
  11. 回车,换行,转义字符“\r”,“\n”是什么关系?
  12. 知乎 Hive Metastore 实践:从 MySQL 到 TiDB
  13. 取消button的点击效果_(Vue动效)6.Vue中列表过渡效果
  14. Android TabActivity与Activity之间的动画跳转(主要Tabhost中跳转出来的动画效果解决)...
  15. 一个可以直接套用的行星齿轮传动比(转速比)结论
  16. AI将png图片转换为矢量图并上传到阿里云iconfont
  17. PreparedStatement 原理
  18. 123456789中间任意加+或-结果等于100
  19. Boost:shared_memory_object --- 共享内存
  20. 关于出版物经营许可证

热门文章

  1. Beacon技术是什么?
  2. 如何评估并管理供应商绩效
  3. 理解前端的 Middleware 原理与实现
  4. 36款顶级的开源音频/视频应用程序
  5. eclipse 项目没错却有红叉(解决办法)
  6. ZZNU-OJ-2119 : 告辞,【卡特兰数列,组合数学】
  7. onmouseenter与onmouseover区别
  8. 紫光展锐 虎贲T610、T618安卓4g核心板 性能参数对比
  9. tensorflow_addons(tfa)安装与使用
  10. Stream API