leetcode150. 逆波兰表达式求值

91 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

前言

继续学习栈与队列,今天做leetcode150题.逆波兰表达式求值。分享后缀表达式相关知识。

题目

废话不多说了,先上题目:

题目就是根据逆波兰表示法,求表达式的值。不过题目限制好了条件,表达式总会得出有效数值且不存在除数为 0 的情况。

后缀表达式

可能大家听到逆波兰表达式会有些懵,其实逆波兰表达式并不是什么高深的概念,就是我们数据结构中熟悉的后缀表达式,是栈的一种很好的实现。

image.png

那么我们也许会觉得普通的写法(也就是中缀表达式)非常好了,便于理解。为什么要有后缀表达式呢?

由于计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序,所以逆波兰式在计算机看来是比较简单易懂的结构。

中缀表达式转后缀表达式

  1. 字母直接输出
  2. 栈空直接入栈
  3. 遍历时遇到"+"或者"-"需要退栈(弹出),退到栈中遇到"+"或者"-"停止,将栈中的"+"或者"-"输出,自己入栈;或者遇到"("停止,将自己入栈。
  4. 遍历时遇到")"需要退栈,遇到"("停止,将"("弹出栈。

后缀表达式的计算

从左到右扫描表达式,遇到数字入栈,遇到操作符取出栈顶的两个元素进行操作,然后将结果压入栈。

解题方法

了解了中缀表达式的一些基本知识后,我们就可以开始做题啦。后缀表达式的计算与1047.删除字符串中的所有相邻重复项有一些相似,遇到操作符取出栈顶的两个元素进行操作。

代码实现

/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function(tokens) {
    const s = new Map([
        ["+", (a, b) => a * 1  + b * 1],
        ["-", (a, b) => b - a],
        ["*", (a, b) => b * a],
        ["/", (a, b) => (b / a) | 0]
    ]);
    const stack = [];
    for (const i of tokens) {
        if(!s.has(i)) {
            stack.push(i);
            continue;
        }
        stack.push(s.get(i)(stack.pop(),stack.pop()))
    }
    return stack.pop();
};