【每日一题】栈系列(1) —— 基本计算器

写在前面:大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我热爱AI、热爱分享、热爱开源! 这博客是我对学习的一点总结与记录。如果您也对 深度学习、机器视觉、算法、Python、C++ 感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


一、基本计算器

(1) 题目描述

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

示例 1:
输入:s = "1 + 1"
输出:2

示例 2:
输入:s = " 2-1 + 2 "
输出:3

示例 3:
输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23

提示:
1 <= s.length <= 3 * 105
s 由数字、'+''-''('')'、和 ' ' 组成
s 表示一个有效的表达式

(2) 解题思路

总体思路:字符串中一共包含6种字符:{ +, -, (, ), 数字, 空格 }。在数学中,我们进行带括号的加减运算有两种方法:

  1. 先计算括号内,在计算括号外,从左往右依次计算
  2. 首先去掉所有的括号,且去括号后要变号,然后从左往右依次计算。

相比较而言,第二种方法更直接。我们选择第二种方法来实现。

如果要展开表达式中所有的括号,则得到的新表达式中,数字本身不会发生变化,只是每个数字前面的符号会发生变化。
因此,我们考虑使用一个取值为{−1,+1} 的整数 sign 代表「当前」的符号。根据括号表达式的性质,它的取值:

  • 与字符串中当前位置的运算符有关
  • 如果当前位置处于一系列括号之内,则也与这些括号前面的运算符有关:每当遇到一个以 -− 号开头的括号,则意味着此后的符号都要被「翻转」。

考虑到第二点,我们需要维护一个栈 stk,其中栈顶元素记录了当前位置所处的每个括号所 「共同形成」的符号。因此,数字加减的符号实际由两部分决定:

  1. 数字本身前面的+、-符号。这一部分,通过判断 ‘+’ 后者 ‘-’ ,可直接给sign取正或者负
  2. 数字外的一系列括号。这一部分,根一系列括号有关。如果括号前是+,则括号内部不需要变号,如果是负,则需要变号。因此括号前的符号特别重要,且括号是由作用范围的,以正括号开始,反括号结束,所以需要用栈stk来存储符号,且栈顶stk.top()表示的是当前的符号。

C++实现如下:

class Solution {
public:
    int calculate(string s) {
        stack<int> stk;
        stk.push(1);
        int sign = 1;

        int ans = 0;
        int n = s.length();
        int i = 0;
        while (i < n) {
            if (s[i] == ' ') {
                i++;
            } else if (s[i] == '+') {
                sign = stk.top();
                i++;
            } else if (s[i] == '-') {
                sign = -stk.top();
                i++;
            } else if (s[i] == '(') {
                stk.push(sign);
                i++;
            } else if (s[i] == ')') {
                stk.pop();
                i++;
            } else {
                long num = 0;
                while (i < n && s[i] >= '0' && s[i] <= '9') {
                    num = num * 10 + s[i] - '0';
                    i++;
                }
                ans += sign * num;
            }
        }
        return ans;
    }
};

测试结果:
在这里插入图片描述
复杂度分析:

  • 时间复杂度:O(n),其中 n 为字符串 s 的长度。
  • 空间复杂度:O(n),其中 n 为字符串 s 的长度。空间复杂度主要取决于栈的空间,栈中的元素数量不超过 n。

由于水平有限,博客中难免会有一些错误,有纰漏之处恳请各位大佬不吝赐教!

在这里插入图片描述
推荐文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI 菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值