[LeetCode] 772. Basic Calculator III

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +, -, *, / operators , open ( and closing parentheses ) and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid. All intermediate results will be in the range of [-2147483648, 2147483647].

Follow up: Could you solve the problem without using built-in library functions.

Example 1:

Input: s = "1 + 1"
Output: 2
Example 2:

Input: s = " 6-4 / 2 "
Output: 4
Example 3:

Input: s = "2*(5+5*2)/3+(6/2+8)"
Output: 21
Example 4:

Input: s = "(2+6* 3+5- (3*14/7+2)*5)+3"
Output: -12
Example 5:

Input: s = "0"
Output: 0

Constraints:

1 <= s <= 104
s consists of digits, '+', '-', '*', '/', '(', ')' and ' '.
s is a valid expression.

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

基本计算器 III。

题意是前两个版本的综合,既要处理四则运算,又要处理带括号的情形。

思路是递归 + 栈。我参考了这个帖子。为什么要用栈,是为了在遇到符号的时候,你要计算局部结果;为什么要用递归,是因为你不知道到底有多少层括号的嵌套,而且因着有乘除法的关系,我们必须先计算好括号内的内容,才能把括号内的局部结果拿出来参与别的运算。这里我们一开始需要一个全局变量index来帮助track到底走到input字符串的什么位置上了。然后我们开始遍历input,这里我们还是像前两个版本一样创建两个变量,sign表示符号,num表示遇到的数字,这里都很正常。当遇到一个左括号的时候,括号内的局部结果 num 就需要用递归来计算了。

时间O(n!) - worst case

空间O(n)

Java实现

 1 class Solution {
 2     private int index = 0;
 3 
 4     public int calculate(String s) {
 5         char[] ch = s.toCharArray();
 6         return cal(ch);
 7     }
 8 
 9     private int cal(char[] ch) {
10         Deque<Integer> stack = new ArrayDeque<>();
11         int num = 0;
12         char sign = '+';
13         while (index < ch.length) {
14             char c = ch[index];
15             if (Character.isDigit(c)) {
16                 num = num * 10 + (c - '0');
17             }
18             if (c == '(') {
19                 index++; // index指针指到下一个字符
20                 num = cal(ch);
21             }
22 
23             // 当遇到了新的运算符,就要对上一个运算符sign和累计的数字num作运算
24             // 空格直接无视,i继续前进
25             // 遇到字符串末尾,肯定是要结算的
26             if (!Character.isDigit(c) && c != ' ' || index == ch.length - 1) {
27                 // int pre = 0;
28                 if (sign == '+') {
29                     stack.push(num);
30                 } else if (sign == '-') {
31                     stack.push(-num);
32                 } else if (sign == '*') {
33                     stack.push(stack.pop() * num);
34                 } else if (sign == '/') {
35                     stack.push(stack.pop() / num);
36                 }
37                 sign = c;
38                 num = 0;
39             }
40             if (c == ')') {
41                 break; //阶段,后面开始计算局部结果,返回
42             }
43             index++;
44         }
45 
46         int res = 0;
47         while (!stack.isEmpty()) {
48             res += stack.pop();
49         }
50         return res;
51     }
52 }

相关题目

224. Basic Calculator

227. Basic Calculator II

772. Basic Calculator III

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14040192.html