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 }
相关题目