「前端刷题」227.基本计算器 II(MEDIUM)

166 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

题目(Basic Calculator II)

链接:https://leetcode-cn.com/problems/basic-calculator-ii
解决数:970
通过率:44.2%
标签:栈 数学 字符串 
相关公司:facebook amazon microsoft 

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

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

你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。

注意: 不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

 

示例 1:

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

示例 2:

输入: s = " 3/2 "
输出: 1

示例 3:

输入: s = " 3+5 / 2 "
输出: 5

 

提示:

  • 1 <= s.length <= 3 * 105
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

思路

遍历:

  • 如果为数字 对num赋值 (* 10 是处理多位数字情况)
  • 如果 ”+“ 将num入栈
  • 如果 ”-“ 将-num入栈
  • 如果 ”* /“ 将栈顶元素取出 运算后入栈(相除存在计算结果包含小数情况,| 0 逻辑运算后可去除小数部分)
var calculate = function(s) {
    s = s.trim()
    const stack = []
    let preSign = '+', num = 0, n = s.length
    for (let i = 0; i < n; i++) {
        if (s[i] >= '0') num = num * 10 + (s[i] - '0')
        if (isNaN(Number(s[i])) || i === n - 1){
            switch (preSign) {
                case '+':
                    stack.push(num)
                    break;
    
                case '-':
                    stack.push(-num)
                    break;
    
                case '*':
                    stack.push(stack.pop() * num)
                    break;
    
                default:
                    stack.push(stack.pop() / num | 0)
                    break;
            }
            preSign = s[i];
            num = 0;
        }
    }
    return  stack.reduce((a,b) => { return a + b }, 0)
};
class Solution:
    def calculate(self, s: str) -> int:
        n = len(s)
        stack = []
        preSign = '+'
        num = 0
        for i in range(n):
            if s[i] != ' ' and s[i].isdigit():
                num = num * 10 + ord(s[i]) - ord('0')
            if i == n - 1 or s[i] in '+-*/':
                if preSign == '+':
                    stack.append(num)
                elif preSign == '-':
                    stack.append(-num)
                elif preSign == '*':
                    stack.append(stack.pop() * num)
                else:
                    stack.append(int(stack.pop() / num))
                preSign = s[i]
                num = 0
        return sum(stack)

or

var calculate = function(s) {
    let stack = [], n = 0, sign = '+' // stack存数字, sign存上一个符号
    for (let i = 0; i <= s.length; i++) {
        if (s[i] === ' ') continue
        if (s[i] <= '9' && s[i] >= '0') {
            n = n * 10 + parseInt(s[i])
            continue
        } 
        switch(sign) {
            case '+': stack.push(n); break
            case '-': stack.push(-n); break
            case '*': stack.push(stack.pop()*n); break
            case '/': stack.push(~~(stack.pop()/n)); break
        }
        sign = s[i]
        n = 0
    }
    return stack.reduce((acc, curr) => acc + curr, 0)
};