【做题也是一场游戏】772. 基本计算器 III

1,046 阅读1分钟

题目地址

leetcode-cn.com/problems/ba…

题目描述

实现一个基本的计算器来计算简单的表达式字符串。

表达式字符串只包含非负整数,算符 +、-、*、/ ,左括号 ( 和右括号 ) 。整数除法需要 向下截断 。

你可以假定给定的表达式总是有效的。所有的中间结果的范围为 [231,2311][-2^{31}, 2^{31 - 1}]

示例 1:

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

示例 2:

输入:s = "6-4/2"
输出:4

示例 3:

输入:s = "2*(5+5*2)/3+(6/2+8)"
输出:21

示例 4:

输入:s = "(2+6*3+5-(3*14/7+2)*5)+3"
输出:-12

示例 5:

输入:s = "0"
输出:0

提示:

1 <= s <= 104
s 由整数、'+''-''*''/''('')' 组成
s 是一个 有效的 表达式

题解

将括号里的表达式作为一个计算单元,递归计算值,相当于将原式转化为加减乘除,相当于 227. 基本计算器 II

class Solution {
    public int calculate(String s) {
        
        return doCalculate(s.toCharArray(), -1)[0];
    }

    private int[] doCalculate(char[] array, int start) {
        int i = start + 1;
        Deque<Integer> stack = new LinkedList<>();
        int leftCount = 1;
        while (i < array.length && array[i] != ')') {

            if (array[i] == '(') {
                int[] temp = doCalculate(array, i);
                stack.offerLast(temp[0]);
                i = temp[1] + 1;
                continue;
            }

            if (array[i] == '+' || array[i] == '-' || array[i] == '*' || array[i] == '/') {
                if (array[i + 1] == '(') {
                    int[] temp = doCalculate(array, i + 1);
                    if (array[i] == '+') {
                        stack.offerLast(temp[0]);
                    } else if (array[i] == '-') {
                        stack.offerLast(-temp[0]);
                    } else if (array[i] == '*') {
                        stack.offerLast(temp[0] * stack.pollLast());
                    } else {
                        stack.offerLast(stack.pollLast() / temp[0]);
                    }
                    
                    i = temp[1] + 1;
                    continue;
                }
            }
            char tempChar = array[i];
            int number = (tempChar >= '0' && tempChar <= '9') ? tempChar - '0' : 0;
            i++;
            while (i < array.length && array[i] >= '0' && array[i] <= '9') {
                    number = number * 10 + (array[i] - '0');
                    i++;
            }
            switch(tempChar) {
                case '+':
                    stack.offerLast(number);
                    break;
                case '-':
                    stack.offerLast(-number);
                    break;
                case '*':
                    stack.offerLast(stack.pollLast() * number);
                    break;
                case '/':
                    stack.offerLast(stack.pollLast() / number);
                    break;
                default: 
                    stack.offerLast(number);
                    break;
            }
        }
        int result = 0;
        while (!stack.isEmpty()) { 
            result += stack.pollLast();
        }
        return new int[]{result, i};

    }
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 为字符串 ss 的长度。需要遍历字符串 ss 一次,计算表达式的值。

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