算法打卡第二十天|LeetCode 150. 逆波兰表达式求值|栈的经典应用
算法打卡第二十天LeetCode 150. 逆波兰表达式求值栈的经典应用今天是算法打卡第20天我学习了LeetCode 150. 逆波兰表达式求值这道题作为栈的又一经典应用题它的解题思路很巧妙第一次接触很难直接想到解法跟着视频讲解梳理逻辑后彻底理解了栈在表达式计算中的核心作用下面分享我的完整学习笔记。题目回顾题目链接https://leetcode.cn/problems/evaluate-reverse-polish-notation/题目描述给你一个字符串数组 tokens 表示一个根据逆波兰表示法表示的算术表达式。请你计算该表达式的值返回整数结果。逆波兰表达式后缀表达式规则- 整数包括负数作为运算数- 运算符仅包含 、 - 、 * 、 /- 每个运算符对应两个运算数表达式始终有效- 除法结果需向零截断舍弃小数部分保留整数示例输入 tokens [2,1,,3,*]输出 9解释该逆波兰表达式对应普通算术表达式为 ((2 1) * 3) 9输入 tokens [10,6,9,3,,-11,*,/,*,17,,5,]输出 22解题核心为什么选择栈逆波兰表达式求值是栈的典型应用场景这类表达式的计算逻辑天然适配栈的后进先出特性1. 逆波兰表达式的运算顺序遇到数字则存储遇到运算符则取出最近两个数字计算2. 栈可以完美记录遍历过程中的运算数栈顶始终是最近的待运算数字3. 遇到运算符时只需弹出两个栈顶运算数计算后将结果重新入栈最终栈中剩余数字就是表达式结果。关键注意点弹出的两个数字先弹出的是右运算数后弹出的是左运算数减法和除法需注意运算顺序避免计算错误详细解题思路1. 初始化一个空栈用于存储遍历过程中的运算数和中间计算结果2. 遍历字符串数组中的每一个元素- 如果当前元素是数字包括负数将其转换为整数后入栈- 如果当前元素是运算符- 弹出栈顶第一个元素作为右运算数- 弹出栈顶第二个元素作为左运算数- 根据运算符执行对应计算除法需遵循向零截断规则- 将计算结果重新压入栈中3. 遍历完成后栈中仅剩一个数字即为表达式最终求值结果。代码实现整理了常用语言的实现代码逻辑清晰贴合解题思路C 实现cppclass Solution {public:int evalRPN(vectorstring tokens) {long long st; // 用long long避免数值溢出for (auto token : tokens) {// 判断是否为运算符if (token || token - || token * || token /) {// 弹出右运算数、左运算数long long num1 st.top();st.pop();long long num2 st.top();st.pop();// 执行对应运算if (token ) st.push(num2 num1);if (token -) st.push(num2 - num1);if (token *) st.push(num2 * num1);if (token /) st.push(num2 / num1);} else {// 数字转换为整数入栈st.push(stoll(token));}}return st.top();}};Python 实现pythonclass Solution:def evalRPN(self, tokens: List[str]) - int:stack []for token in tokens:if token in -*/:num1 stack.pop()num2 stack.pop()if token :stack.append(num2 num1)elif token -:stack.append(num2 - num1)elif token *:stack.append(num2 * num1)else:# 除法向零截断stack.append(int(num2 / num1))else:stack.append(int(token))return stack[0]Java 实现javaclass Solution {public int evalRPN(String[] tokens) {Integer();for (String s : tokens) {if (s.equals() || s.equals(-) || s.equals(*) || s.equals(/)) {int num1 stack.pop();int num2 stack.pop();switch (s) {case :stack.push(num2 num1);break;case -:stack.push(num2 - num1);break;case *:stack.push(num2 * num1);break;case /:stack.push(num2 / num1);break;}} else {stack.push(Integer.parseInt(s));}}return stack.pop();}}复杂度分析- 时间复杂度O(n)n为字符串数组长度每个元素仅入栈、出栈一次遍历一次即可完成计算- 空间复杂度O(n)最坏情况下栈中存储所有运算数占用n个空间。学习心得这道题让我对栈的应用有了更深刻的理解看似复杂的表达式计算借助栈后进先出的特性就能轻松解决。第一次接触逆波兰表达式确实会无从下手但理清「数字入栈、运算符取数计算」的核心逻辑后会发现栈完美解决了「寻找最近运算数」的问题。同时也总结了这类栈表达式题的易错点减法和除法的运算数顺序不能颠倒一定要牢记先弹出的是右运算数后弹出的是左运算数。后续遇到中缀表达式转后缀表达式、括号匹配、相邻元素消除等问题都可以第一时间想到用栈解决栈的核心就是记录最近状态、快速回溯处理学习资料- 题目链接https://leetcode.cn/problems/evaluate-reverse-polish-notation/- 视频讲解https://www.bilibili.com/video/BV1kd4y1o7on
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2574027.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!