美文网首页算法
224. 基本计算器

224. 基本计算器

作者: 红树_ | 来源:发表于2023-05-10 19:22 被阅读0次

    山不辞土,故能成其高;海不辞水,故能成其深!

    参考224. 基本计算器

    题目

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

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

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

    解题思路

    • 枚举去除括号:枚举时入栈,直到碰到右括号,运算到栈顶的左括号,最后计算一次。
    • 括号展开:对左括号前面的符号入栈,右括号时出栈,因为只有+-,可以对括号里面的数进行最终的符号确定。

    枚举去除括号

    class Solution {
        public int calculate(String s) {
            //考虑栈 因为没有乘除只需要考虑括号先执行
            StringBuilder ans = new StringBuilder();
            for(char c : s.toCharArray()) {
                if(c == ' ') continue;
                if(c == ')') { //右括号开始计算到栈顶的左括号
                    int index = ans.lastIndexOf("(");
                    int res = eval(ans.substring(index+1));
                    ans.delete(ans.lastIndexOf("("),ans.length());//左括号出栈
                    ans.append(String.valueOf(res));//结果入栈
                }else {
                    ans.append(c);
                }
            }
            return eval(ans.toString());
        }
        //计算不含括号的+/- 主要注意多位数字的计算
        public int eval(String s) {
            char lastCalc = '+',lastChar = 0;
            int res = 0,lastNum = 0;
            for(char c : s.toCharArray()) {
                if(c == '+' || c == '-'){
                    if(lastCalc == '+') res += lastNum;
                    else res -= lastNum;
                    lastNum = 0;
                    if(lastChar == c) lastCalc = '+';//简化判断 lastChar == '-' && c == '-'
                    //else if(lastChar == '-' && c == '+')lastCalc = '-';//不合法
                    else lastCalc = c;
                }else {
                    lastNum = lastNum*10 + (c-'0');
                }
                lastChar = c;
            }
            return res + (lastCalc == '+'?lastNum : -lastNum);
        }
    }
    

    复杂度分析

    • 时间复杂度:O(n)n为表达式字符串长度,最坏的情况下字符串会被访问两次耗时2n
    • 空间复杂度:O(n),中间使用空间不超过n

    括号展开

    class Solution {
        public int calculate(String s) {
            Deque<Integer> st = new ArrayDeque<Integer>(); // 存储正负号
            int ans = 0, num = 0, op = 1;//符号可用op或sign表示
            st.push(op);
            for (char c : s.toCharArray()) {
                if (c == ' ') continue;
                else if (c >= '0' && c <= '9') num = num * 10 + (c - '0');
                else {
                    ans += op * num;
                    num = 0; //重置上次记录
    
                    if (c == '+') op = st.peek();
                    else if (c == '-') op = -st.peek();
                    else if (c == '(') st.push(op); // 将括号前符号放入栈顶
                    else st.pop();//')'
                }
            }
            return ans + op * num;
        }
    }
    

    复杂度分析

    • 时间复杂度:O(n),一重循环遍历。
    • 空间复杂度:O(k)k为左括号数量。

    相关文章

      网友评论

        本文标题:224. 基本计算器

        本文链接:https://www.haomeiwen.com/subject/xdejsdtx.html