【每天学习一点算法 2026/04/16】逆波兰表达式求值

每天学习一点算法 2026/04/16

逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

有效的算符为 '+'、'-'、'*' 和 '/' 。

每个操作数(运算对象)都可以是一个整数或者另一个表达式。

两个整数之间的除法总是 向零截断 。

表达式中不含除零运算。

输入是一个根据逆波兰表示法表示的算术表达式。

答案及所有中间计算结果可以用 32 位 整数表示。

复制代码
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

根据这两示例我们可以看出符号的前两位就是参与计算的数字,那么我们就可以找出每一步计算的符号和参与计算的数字,用计算结果替换掉他们,直到没有符号,剩下的最后一位就是计算结果

typescript 复制代码
function evalRPN(tokens: string[]): number {
  while (tokens.length > 1) {
    // 找到符号和参数计算的两个数字
    const index = tokens.findIndex(item => item == '+' || item == '-' || item == '*' || item == '/')
    const num1 = Number(tokens[index - 2])
    const num2 = Number(tokens[index - 1])
    // 根据符号计算结果,并替换掉这三个元素
    switch (tokens[index]) {
      case '+': {
        tokens.splice(index - 2, 3, (num1 + num2).toString())
        break
      }
      case '-': {
        tokens.splice(index - 2, 3, (num1 - num2).toString())
        break
      }
      case '*': {
        tokens.splice(index - 2, 3, (num1 * num2).toString())
        break
      }
      case '/': {
        tokens.splice(index - 2, 3, Math.trunc(num1 / num2).toString())
        break
      }
    }
  }
  return Number(tokens[0]) // 返回最后结果
};

我们还可以用空间换时间,维护一个栈,然后循环 tokens 所有元素,遇到数字就压栈,遇到符号就弹出两个参与计算的数字,再将计算结果压栈,遍历完所有的元素,最后栈里就是最终的计算结果

typescript 复制代码
function evalRPN(tokens: string[]): number {
  const stack: number[] = []
  for (let i = 0; i < tokens.length; i++) {
    switch (tokens[i]) {
      case '+': {
        const num2 = stack.pop()
        const num1 = stack.pop()
        stack.push(num1 + num2)
        break
      }
      case '-': {
        const num2 = stack.pop()
        const num1 = stack.pop()
        stack.push(num1 - num2)
        break
      }
      case '*': {
        const num2 = stack.pop()
        const num1 = stack.pop()
        stack.push(num1 * num2)
        break
      }
      case '/': {
        const num2 = stack.pop()
        const num1 = stack.pop()
        stack.push(Math.trunc(num1 / num2))
        break
      }
      default: {
        stack.push(Number(tokens[i]))
      }
    }
  }
  return stack.pop()
};

题目来源:力扣(LeetCode)

相关推荐
宝绿特塑业再生科技2 小时前
改性HDPE再生颗粒在户外家具挤出发泡板材中的色差控制与高品质价值重构
经验分享·科技·学习·生活·1024程序员节·户外家具
企业数字化笔记4 小时前
视频人体姿态怎么做三维可视化?2D关键点、深度局限与技术选型
人工智能·算法·音视频
andrsted4 小时前
练题簿在线免费刷题:让整理过的资料,变成能反复练习的题库
学习·微信小程序·小程序·学习方法·刷题·1024程序员节
?abc!5 小时前
(数组)581. 最短无序连续子数组
数据结构·算法·leetcode
Alsn865 小时前
Windows 安装 Ollama 及本地模型部署
学习·1024程序员节
欣欣之王来了6 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
小郎君6587 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧7 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
Shimeri8 小时前
越卷越像:我用遗传算法做了个"内卷"实验
算法·three.js·数据可视化·遗传算法·进化算法
Evand J9 小时前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波