【LeetCode】150. 逆波兰表达式求值
实现思路
- 栈结构:利用切片模拟栈,存储运算过程中的中间结果。
- 操作符处理:遇到运算符时,从栈顶弹出两个操作数,按运算符计算后将结果重新压栈。
- 运算顺序:注意减法和除法中操作数的顺序(第二个弹出的数是左操作数,第一个是右操作数)。
- 整数除法:Golang 默认的整数除法已实现向零截断,直接使用即可。
func evalRPN(tokens []string) int { stack := []int{} operators := map[string]bool{"+": true, "-": true, "*": true, "/": true} for _, token := range tokens { if _, ok := operators[token]; ok { // 弹出右操作数和左操作数 right := stack[len(stack)-1] left := stack[len(stack)-2] stack = stack[:len(stack)-2] // 执行运算 var res int switch token { case "+": res = left + right case "-": res = left - right case "*": res = left * right case "/": res = left / right } stack = append(stack, res) } else { // 数字入栈 num, _ := strconv.Atoi(token) stack = append(stack, num) } } return stack[0] }
核心逻辑解析
-
栈操作:
- 压栈:遇到数字时通过
strconv.Atoi转换后存入切片。 - 弹栈:遇到运算符时弹出栈顶两个元素,按优先级处理后重新压栈。
- 压栈:遇到数字时通过
-
运算顺序控制:
right := stack[len(stack)-1] // 右操作数(后入栈) left := stack[len(stack)-2] // 左操作数(先入栈)
例如对表达式
["4","13","5","/","+"]:- 先计算
13/5=2(右操作数5,左操作数13)。 - 再计算
4+2=6(右操作数2,左操作数4)。
- 先计算
-
边界处理:
- 题目保证输入有效,无需处理非法运算符或空栈情况。
- 最终栈中仅剩一个元素即为结果。
复杂度分析
| 指标 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 遍历所有 token 一次 |
| 空间复杂度 | O(n) | 栈最多存储 n/2+1 个元素 |
示例验证
func main() { fmt.Println(evalRPN([]string{"2","1","+","3","*"})) // 输出 9 fmt.Println(evalRPN([]string{"4","13","5","/","+"})) // 输出 6 fmt.Println(evalRPN([]string{"10","6","9","3","+","-11","*","/","*","17","+","5","+"})) // 输出 22 }
算法优势
- 无歧义性:无需处理运算符优先级和括号,直接按顺序计算。
- 高效性:单次遍历即可完成计算,时间复杂度最优。
- 低内存占用:栈空间仅存储中间结果,内存使用与表达式复杂度线性相关。

浙公网安备 33010602011771号