[LeetCode] 224. Basic Calculator
Given a string s
representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval()
.
Example 1:
Input: s = "1 + 1" Output: 2
Example 2:
Input: s = " 2-1 + 2 " Output: 3
Example 3:
Input: s = "(1+(4+5+2)-3)+(6+8)" Output: 23
Constraints:
1 <= s.length <= 3 * 105
s
consists of digits,'+'
,'-'
,'('
,')'
, and' '
.s
represents a valid expression.'+'
is not used as a unary operation (i.e.,"+1"
and"+(2 + 3)"
is invalid).'-'
could be used as a unary operation (i.e.,"-1"
and"-(2 + 3)"
is valid).- There will be no two consecutive operators in the input.
- Every number and running calculation will fit in a signed 32-bit integer.
基本计算器。
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/basic-calculator
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意是实现一个基本的计算器来计算一个简单的字符串表达式的值。注意这个题是不需要处理乘法和除法的,只需要处理加减法和带括号的情形。
思路是用stack。按字符逐个遍历input,因为没有无效的case所以不需要处理一些奇奇怪怪的比如是不是字母的case。一开始遍历的时候设置一个变量res和一个变量sign记录最后的结果和结果的正负号。计算数字的时候记得看数字是不是有多个digit。注意这道题是会把运算符号放入stack的,弹出的时候加减运算是会依赖运算符号的正负情况的。
最后着重讲一下带括号的部分,如果你遇到一个左括号,就需要把之前的res和sign加入stack,这里顺序不能错,先加res再加sign,并且把res和sign都重新设置成0和1,使得他们可以继续用来记录括号内的部分的结果和正负情况。当遇到右括号的时候则开始结算括号内的结果。此时的res是记录了括号内的部分的结果,stack.pop()会先弹出sign;再弹一次的时候就得到了括号部分之前的res,再相加就得到最终的结果了。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int calculate(String s) { 3 Deque<Integer> stack = new ArrayDeque<>(); 4 int res = 0; 5 int sign = 1; 6 for (int i = 0; i < s.length(); i++) { 7 if (Character.isDigit(s.charAt(i))) { 8 int num = s.charAt(i) - '0'; 9 while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) { 10 num = num * 10 + s.charAt(i + 1) - '0'; 11 i++; 12 } 13 res += num * sign; 14 } else if (s.charAt(i) == '+') { 15 sign = 1; 16 } else if (s.charAt(i) == '-') { 17 sign = -1; 18 } else if (s.charAt(i) == '(') { 19 stack.push(res); 20 stack.push(sign); 21 res = 0; 22 sign = 1; 23 } else if (s.charAt(i) == ')') { 24 // 第一次pop的是符号,第二次pop的是再之前的一个数字 25 res = res * stack.pop() + stack.pop(); 26 } 27 } 28 return res; 29 } 30 }
相关题目