题目描述
思路解析动画文字版
括号 = “先把外面的进度存起来,进去单独算完再接回来”,这就是栈。
上排是整条表达式(固定不变),下面竖着的是栈,里面存“括号外面没算完的进度”。
碰到 ( :把“外面算到一半的 result 和 sign”整对压进栈,括号里从 0 干净地重新算。
第 1 个是数字 1,先攒着(num=1),等碰到符号或括号再结算。
碰到 +:把刚攒好的数按当前符号加进 result,再用 + 决定下一个数是正还是负。
碰到 ( :把“外面算到一半的 result 和 sign”整对压进栈,括号里从 0 干净地重新算。
第 4 个是数字 4,先攒着(num=4),等碰到符号或括号再结算。
碰到 +:把刚攒好的数按当前符号加进 result,再用 + 决定下一个数是正还是负。
第 6 个是数字 5,先攒着(num=5),等碰到符号或括号再结算。
碰到 +:把刚攒好的数按当前符号加进 result,再用 + 决定下一个数是正还是负。
第 8 个是数字 2,先攒着(num=2),等碰到符号或括号再结算。
碰到 ) :括号里这段算完了,弹出之前压的那对——括号值先乘上当时的符号,再加回当时的 result,进度就接上了。
碰到 -:把刚攒好的数按当前符号加进 result,再用 - 决定下一个数是正还是负。
第 11 个是数字 3,先攒着(num=3),等碰到符号或括号再结算。
碰到 ) :括号里这段算完了,弹出之前压的那对——括号值先乘上当时的符号,再加回当时的 result,进度就接上了。
碰到 +:把刚攒好的数按当前符号加进 result,再用 + 决定下一个数是正还是负。
碰到 ( :把“外面算到一半的 result 和 sign”整对压进栈,括号里从 0 干净地重新算。
第 15 个是数字 6,先攒着(num=6),等碰到符号或括号再结算。
碰到 +:把刚攒好的数按当前符号加进 result,再用 + 决定下一个数是正还是负。
第 17 个是数字 8,先攒着(num=8),等碰到符号或括号再结算。
最后一个 ) 把括号值合并回来后,整条表达式的结果就是 23。
边界先想清,尤其是负号和空格。
两个高频追问,第二问常被用来加难度。
参考代码
def calculate(s: str) -> int: result, sign, num = 0, 1, 0 stack = [] for c in s: if c.isdigit(): num = num * 10 + int(c) elif c in "+-": result += sign * num num = 0 sign = 1 if c == "+" else -1 elif c == "(": stack.append(result); stack.append(sign) result, sign = 0, 1 elif c == ")": result += sign * num; num = 0 result *= stack.pop() # 栈顶 sign result += stack.pop() # 栈顶 result return result + sign * num复杂度
- 时间:O(n),每个字符只扫一次
- 空间:O(n),最坏全是左括号,全压进栈
易错点
面试追问把动画讲成自己的话
追问为什么不直接转成逆波兰表达式再算?
追问如果再加上乘除该怎么改?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。再去主线里挑下一道练手。
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题