LeetCode热题(JS版) - 227. 基本计算器 II

89 阅读1分钟

问题描述

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

示例

输入:s = "3+2*2"
输出:7

解法

该问题可以使用栈来解决。具体步骤如下:

  • 首先,初始化一个栈 stack 和两个变量 numpreOp

  • 然后,遍历字符串 s 中的每个字符:

    • 如果当前字符是数字字符,则将其转换为整数,并累加到 num 变量上。

    • 如果当前字符是运算符或者字符串 s 的末尾,则根据前面的 preOp 变量来决定如何将 num 入栈:

      • 如果 preOp+,则将 num 直接入栈。
      • 如果 preOp-,则将 -num 入栈。
      • 如果 preOp*,则将栈顶元素乘以 num,并将结果入栈。
      • 如果 preOp/,则将栈顶元素除以 num,并将结果入栈(需要注意整数除法要向零取整)。
    • 如果当前字符是运算符,则将其赋值给 preOp 变量,并将 num 重置为 0。

  • 最后,遍历完整个字符串之后,将栈中所有元素累加起来,即为所求的结果。

代码实现

以下是使用 Typescript 实现的代码:

function calculate(s: string): number {
  const stack = [];
  let num = 0;
  let preOp = "+";

  for (let i = 0; i < s.length; i++) {
    const c = s.charAt(i);

    if (/\d/.test(c)) {
      num = num * 10 + Number(c);
    }

    if (!/\d/.test(c) && c !== " " || i === s.length - 1) {
      switch (preOp) {
        case "+":
          stack.push(num);
          break;
        case "-":
          stack.push(-num);
          break;
        // 乘除要出栈
        case "*":
          stack.push(stack.pop() * num);
          break;
        default:
          stack.push((stack.pop() / num) | 0);// 避免/0
          break;
      }
      num = 0;
      // 更新操作符
      preOp = c;
    }
  }
    
  // 余下的都是相加
  return stack.reduce((a, b) => a + b, 0);
}

时间复杂度分析

由于需要遍历字符串 s 中的每个字符,因此时间复杂度为 O(n)O(n),其中 nn 是字符串 s 的长度。在计算过程中,每个数字最多被入栈和出栈一次,因此空间复杂度为 O(n)O(n)

因此,算法的时间复杂度为 O(n)O(n),空间复杂度也为 O(n)O(n)