• 逆波兰表达式求值(leetcode 150)


    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 
    #include 
    #include 
    #include  
    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 []int
        for _, 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 main
    
    import (
    	"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

  • 相关阅读:
    视野修炼-技术周刊第58期
    JS-基础
    《Java进阶学习+面试宝典》分享给大家
    Android10 dex2oat实践
    Kotlin 协程 知识点
    Mybatis
    洗衣行业在线预约小程序系统源码搭建 支持直播功能+在线预约下单+上门取件
    HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)
    Qt5开发从入门到精通——第七篇一节( 图形视图——动画效果 )
    HW-初始准备
  • 原文地址:https://blog.csdn.net/K346K346/article/details/126837884