[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;
 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         for (index = 0; index < ch.length; index++) {
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                 switch (sign) {
29                     case '+':
30                         stack.push(num);
31                         break;
32                     case '-':
33                         stack.push(-num);
34                         break;
35                     case '*':
36                         pre = stack.pop();
37                         stack.push(pre * num);
38                         break;
39                     case '/':
40                         pre = stack.pop();
41                         stack.push(pre / num);
42                         break;
43                 }
44                 sign = c;
45                 num = 0;//计数归位
46             }
47             if (c == ')') {
48                 break; //阶段,后面开始计算局部结果,返回
49             }
50         }
51 
52         int res = 0;
53         while (!stack.isEmpty()) {
54             res += stack.pop();
55         }
56         return res;
57     }
58 }

 

相关题目

224. Basic Calculator

227. Basic Calculator II

772. Basic Calculator III

LeetCode 题目总结

上一篇:【Basic】SVM(支持向量机)分类算法


下一篇:2021.1.26 蓝桥杯基础练习(BASIC-3 字母图形、BASIC-2 01字串)