LeetCode 224. 基本计算器

题目描述

224. 基本计算器

解法一:用栈模拟(C++)

两个栈,一个存符号,一个存数字

对于符号栈,

  • 左括号直接进栈
  • 右括号不断计算,直到遇到栈中的第一个左括号为止
  • 如果是运算符,先查看栈顶符号,如果为运算符,弹出栈顶运算符计算后,在压入当前运算符

对于数字栈,

  • 遇到计算,就直接弹出两个数字参与运算后将结果压回数字栈,注意减法运算
  • 细节上为了防止第一个数字是负数,我们在数字栈中事先压入 0 元素
class Solution {
public:

    void helper(vector<int>& nums, char op)
    {
        int num1 = nums.back();
        nums.pop_back();
        int num2 = nums.back();
        nums.pop_back();
        if(op=='+')
        {
            num1 += num2;
            nums.push_back(num1);
        }
        else 
        {
            num2 -= num1;
            nums.push_back(num2);
        }
    }

    int calculate(string s) {
        vector<int> nums;
        nums.push_back(0);
        vector<char> ops;
        int tmp, n = s.length(), i = 0;
        char op;
        while(i<n)
        {
            if(isdigit(s[i]))
            {
                tmp = 0;
                while(i<n && isdigit(s[i]))
                {
                    tmp = tmp*10+(s[i]-'0');
                    i++;
                }
                nums.push_back(tmp);
            }
            else if(s[i]!=' ')
            {
                if(s[i]==')')
                {
                    while(ops.back()!='(')
                    {
                        op = ops.back();
                        ops.pop_back();
                        helper(nums, op);
                    }
                    ops.pop_back();
                }
                else if(s[i]!='(')
                {
                    if(!ops.empty() && ops.back()!='(')
                    {
                        op = ops.back();
                        ops.pop_back();
                        helper(nums, op);
                    }
                    ops.push_back(s[i]);
                }
                else ops.push_back(s[i]);
                i++;
            }
            else i++;
        }
        if(!ops.empty())
        {
            op = ops.back();
            ops.pop_back();
            helper(nums, op);
        }
        return nums.back();
    }
};

解法二:栈 + 符号扩展(Python)

我们不把加号、减号看做是运算符,而是看作当前数字的符号,记当前数字为 n u m num num、最终答案 r e s res res,于是有 r e s = r e s + n u m res = res + num res=res+num

如果,这样设定,我们就需要用一个变量来记录数字的符号,即 s i g n sign sign,需要指出的是 s i g n sign sign 记录的是下一个数字的符号

我们有如下的算法流程,

  • 如果当前字符是数字,那么更新参与计算的数字(考虑两位数、三位数等情况)
  • 如果当前字符是加号或者减号,那么需要更新当前的计算的结果 r e s res res,同时置 n u m num num 0 0 0,根据加减号,设置 s i g n sign sign 新的值
  • 如果当前字符是左括号,那么要先计算后面括号内的结果,我们就将当前 r e s res res s i g n sign sign 压入栈中,同时置 r e s res res 0 0 0 s i g n sign sign 1 1 1
  • 如果当前字符是右括号,那么当前括号内结果计算完毕,可以弹出之前栈中内容进行合并
    LeetCode 224. 基本计算器_第1张图片
class Solution:
    def calculate(self, s: str) -> int:
        res, num, sign = 0, 0, 1
        st = []
        for c in s:
            if c.isdigit():
                num = num * 10 + int(c)
            elif c == "+" or c == '-':
                res += sign * num
                num = 0
                sign = 1 if c == "+" else -1
            elif c == "(":
                st.append(res)
                st.append(sign)
                res = 0
                sign = 1
            elif c == ")":
                res += sign * num
                num = 0
                res *= st.pop()
                res += st.pop()
        res += sign * num
        return res

你可能感兴趣的:(题解,leetcode)