【LeetCode227】基本计算器 II(栈)

简介: s 表示一个 有效表达式表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内

一、题目


image.png

1 <= s.length <= 3 ∗ 1 0 5 3 * 10^53∗10

5

s 由整数和算符 (’+’, ‘-’, ‘*’, ‘/’) 组成,中间由一些空格隔开

s 表示一个 有效表达式

表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内

题目数据保证答案是一个 32-bit 整数

二、思路

(1)首先考虑最简单的情况,只有加减法,如3-4+5,首先给第一个数字加上默认初始化的符号+,即+3-4+5,拆分为+3,-4,+5,依次放入栈中求和即得结果。


(2)接着考虑乘除法情况,比如3-4*9+5则需要先求出乘法后再继续像(1)一样进栈相加运算。即直接在switch中加上乘除法的case。


(3)最后一种情况是有括号时,因为括号有递归性质,如3-(1-4*9)+5需要先处理括号内容,其中也有乘法和减法。

c a l c u l a t e ( 3 − ( 1 − 4 ∗ 9 ) + 5 ) calculate(3-(1-4*9)+5)calculate(3−(1−4∗9)+5)

= 3 − c a l c u l a t e ( 1 − 4 ∗ 9 ) + 5 = 3- calculate(1-4*9)+5=3−calculate(1−4∗9)+5

= 3 − ( − 35 ) − 6 = 3 - (-35)-6=3−(−35)−6

即无论有多少层括号的嵌套,都可以通过caculate函数递归调用自己,将括号内容计算成一个数字。


还有一种方法是常规的双栈操作。


三、C++代码

class Solution {
public:
    int calculate(string s) {
        int begin = 0;
        return calHelper(s, begin);
    }
    //i用于记录计算开始的索引
    int calHelper(string s, int& i){
        stack<int> stk;
        char sign = '+';
        int num = 0;
        for(int i = 0; i < s.size(); i++){
            //把str类型转为数字
            char c = s[i];
            if(isdigit(c)){
                num = 10 * num + (c - '0');
            }
            if(c == '('){
                //从i的下一个开始计算,进入递归
                num = calHelper(s, ++i);
                //计算完之后的i指向)所以再++
                i++;
            }
            //如果不是数字,或者不是空格
            if((!isdigit(c) && c != ' ') || i >= s.size() - 1){
                switch(sign){
                    int pre;
                    //拿出前一个数字做对应运算
                    case '+':
                        stk.push(num);
                        break;
                    case '-':
                        stk.push(-num);
                        break;
                    case '*':
                        //top返回栈顶元素
                        pre = stk.top();
                        stk.pop();
                        stk.push(pre * num);
                        break;
                    case '/':
                        pre = stk.top();
                        stk.pop();
                        stk.push(pre / num);
                        break;
                    //更新符号为当前符号,数字清零
                }
                sign = c;
                num = 0;
            }
            //遇到)则回到上一级递归
            if(s[i] == ')'){
                break;
            }
        }
        //将栈中所有结果求和即答案
        int res = 0;
        while(!stk.empty()){
            res += stk.top();
            stk.pop();
        }
        return res;
    }
};
相关文章
|
5月前
|
存储 算法 测试技术
力扣经典150题第五十四题:最小栈
力扣经典150题第五十四题:最小栈
44 0
|
6月前
|
存储 算法 索引
力扣每日一题 6/24 模拟 数组 单调栈
力扣每日一题 6/24 模拟 数组 单调栈
41 0
|
2月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
15 0
|
2月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
26 0
|
4月前
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
35 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
35 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 09. 用两个栈实现队列
使用两个栈实现队列的Python解决方案,包括初始化两个栈、实现在队列尾部添加整数的appendTail方法和在队列头部删除整数的deleteHead方法,以及相应的示例操作。
41 2
|
4月前
|
Python
【Leetcode刷题Python】232. 用栈实现队列
如何使用Python语言通过两个栈来实现队列的所有基本操作,包括入队(push)、出队(pop)、查看队首元素(peek)和判断队列是否为空(empty),并提供了相应的代码实现。
25 0
|
6月前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
6月前
|
存储 算法 数据可视化
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)