【LeetCode 224】Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务

132 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务活动详情

一、题目描述

给定一个表达式,只有加减号、括号和数字,求其值。

二、思路分析

本题我们用了两个栈去处理,一个是数字栈,一个是符号栈,正常情况下,表达式的每一层(每遇到一对括号就认为是新的一层)只占一个坑位,新加一个数,就和前面的数处理、合并起来。

如果遇到了括号(也就是进入了更里面的一层),就暂时没办法合并了,只能都存起来;待到遇到右括号的时候,此时该层在数字栈中也只占一个坑位,直接把左括号踢出去就好了,踢出去之后需要和上一层已经占有坑位的那个数再合并一下。

这里有个巧合就是我写的时候为了处理每层第一个数是负数的情况,我先放置了一个 0,这也就巧合地保证了遇到右括号,和上一层合并的时候一定有一个数字能和它合并,避免了 ((1+1)) 的问题,不用再去判断上一层还是一个括号——即没有数字合并,然后出错的情况。

三、AC代码

class Solution {
public:
    long long p=0,l=0,i=0,ck=0;
    stack<long long> num;
    stack<char> op;

    // 计算一次
    void cacl(){
        char ch = op.top(); op.pop();
        int y = num.top(); num.pop();
        int x = num.top(); num.pop();
        if (ch == '+') num.push(x+y);
        if (ch == '-') num.push(x-y);
        return;
    }

    int calculate(string s) {
        // 初始时需要先放入一个零,处理符号在前面的情况
        ck = 1;
        num.push(0);
        l=s.length();
        long long now = 0;

        while (i < l) {
            int flag=0;
            
            // ck用来标识我们放置了一个零,如果后面不是负号,就得补一个加号,不然符号就会错乱了
            if (ck == 1) {
                ck = 0;
                if (s[i] != '-') op.push('+');
            }
            
            while (i < l & s[i]>='0' && s[i]<='9') {
                now = now * 10 + s[i] - '0';
                i++;
                flag=1;
            }

            if (flag) {
                num.push(now);
                now = 0;
                cacl();
            }

            if (s[i] == ' ') {
                i++;
            } else
            if (s[i] == '(') {
                num.push(0);
                ck = 1;
                op.push(s[i]);
                i++;
            } else 
            if (s[i] == ')') {
                op.pop();
                cacl();
                i++;
            } else {
                op.push(s[i]);
                i++;
            }
        }
        long long ans= num.top();
        return ans;
    }
};

四、总结

与其说它是一道栈的题目,不如说它是道恶心人的大模拟。看看下面的图就知道我有多崩溃了,昨天写的时候一直解决不了负号在前面的情况,写了很多补丁,结果越写bug越多,很难受,索性停下来不写了(这也是我一个很好的经验,遇到一些烦人的东西,需要积极面对没错,但是!不要陷进去,感觉自己有点乱了就强制停下来休息,隔了一整天再继续想一想,一下子就解决了)

image.png