题目描述
思路解析动画文字版
记住这一条,下面每个 token 都在套它。
栈一开始是空的。指针从最左边的 token 出发。
第 0 个 token 是数字 10,数字一律直接压进栈。
10 进栈,现在栈里有 1 个数,栈顶是 10。
第 1 个 token 是数字 6,数字一律直接压进栈。
6 进栈,现在栈里有 2 个数,栈顶是 6。
第 2 个 token 是数字 9,数字一律直接压进栈。
9 进栈,现在栈里有 3 个数,栈顶是 9。
第 3 个 token 是数字 3,数字一律直接压进栈。
3 进栈,现在栈里有 4 个数,栈顶是 3。
第 4 个 token 是运算符 +。弹出栈顶两个数:先弹的 3 是右操作数,后弹的 9 是左操作数。
算 9 加 3 = 12(顺序是左 加 右,别弹反)。把结果 12 压回栈,替换掉刚弹走的两个数。
第 5 个 token 是数字 -11,数字一律直接压进栈。
-11 进栈,现在栈里有 4 个数,栈顶是 -11。
第 6 个 token 是运算符 *。弹出栈顶两个数:先弹的 -11 是右操作数,后弹的 12 是左操作数。
算 12 乘 -11 = -132(顺序是左 乘 右,别弹反)。把结果 -132 压回栈,替换掉刚弹走的两个数。
第 7 个 token 是运算符 /。弹出栈顶两个数:先弹的 -132 是右操作数,后弹的 6 是左操作数。
算 6 除 -132 = 0(顺序是左 除 右,别弹反)。把结果 0 压回栈,替换掉刚弹走的两个数。
第 8 个 token 是运算符 *。弹出栈顶两个数:先弹的 0 是右操作数,后弹的 10 是左操作数。
算 10 乘 0 = 0(顺序是左 乘 右,别弹反)。把结果 0 压回栈,替换掉刚弹走的两个数。
第 9 个 token 是数字 17,数字一律直接压进栈。
17 进栈,现在栈里有 2 个数,栈顶是 17。
第 10 个 token 是运算符 +。弹出栈顶两个数:先弹的 17 是右操作数,后弹的 0 是左操作数。
算 0 加 17 = 17(顺序是左 加 右,别弹反)。把结果 17 压回栈,替换掉刚弹走的两个数。
第 11 个 token 是数字 5,数字一律直接压进栈。
5 进栈,现在栈里有 2 个数,栈顶是 5。
第 12 个 token 是运算符 +。弹出栈顶两个数:先弹的 5 是右操作数,后弹的 17 是左操作数。
算 17 加 5 = 22(顺序是左 加 右,别弹反)。把结果 22 压回栈,替换掉刚弹走的两个数。
所有 token 处理完(全部变灰),栈里只剩一个数 22,它就是整个表达式的值。
小例子先在脑子里跑一遍。
两个高频追问。
参考代码
def evalRPN(tokens): st = [] for t in tokens: if t in ("+", "-", "*", "/"): b = st.pop(); a = st.pop() if t == "+": st.append(a + b) elif t == "-": st.append(a - b) elif t == "*": st.append(a * b) else: st.append(int(a / b)) # 向零截断 else: st.append(int(t)) return st[0]复杂度
- 时间:O(n),每个 token 只进出栈常数次
- 空间:O(n),最坏全是数字,栈装一半
易错点
面试追问把动画讲成自己的话
追问为什么逆波兰表达式不需要括号?
追问怎么把中缀表达式转成逆波兰?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
括号生成
LeetCode 22 · 中等 · 沿着 栈 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题