题目描述 & 链接
Leetcode 772: 是Leetcode 224. Basic Calculator(计算器) 题目的进阶版,给定一个计算表达式,运算符包括左右括号,"+ - * /" 运算,求最后计算结果
题目思路
与Leetcode 224. Basic Calculator(计算器)是相同的,利用双栈(符号栈,数字栈)求解,具体可以参考前面链接,唯一需要改进的是加入乘法和除法并分配为最高优先级,在维护符号栈时,当新符号优先级比栈顶小或相同时,触发计算,直到栈顶空或者比当前有限级小
- 当新符号比栈顶小时触发计算 - 是遵循乘除法优先于加减法
- 举例:2*4 - 8 ->当" - " 准备进栈时,应该将前面乘法先计算完才行
- 当新符号与栈顶同级触发计算 - 是为了避免下面这种情况
- 举例: 2-1+2 -> 如果同级进栈不触发计算,会导致结果为-1
- 举例2: 10/2/5 -> 如果同级进栈不触发计算,会导致结果为10/0
代码如下
class Solution {
public int calculate(String s) {
// 优先级
HashMap<Character, Integer> prio = new HashMap<>();
prio.put('(', 1);
prio.put('+', 2);
prio.put('-', 2);
prio.put('*', 3);
prio.put('/', 3);
Deque<Character> ops = new ArrayDeque<>();
Deque<Integer> stk = new ArrayDeque<>();
// 避免负数出现
// stk.push(0);
for(int i=0; i<s.length();) {
char ch = s.charAt(i);
if(ch=='(') {
ops.push(ch);
i++;
} else if(Character.isDigit(ch)) {
String tmp = "";
while(i<s.length() && Character.isDigit(s.charAt(i))) {
tmp+=s.charAt(i);
i++;
}
stk.push(Integer.parseInt(tmp));
} else if(ch==')') {
while(!ops.isEmpty() && ops.peek()!='(') {
calculate(ops, stk);
}
ops.pop(); // pop (
i++;
} else {
// 同级或者更小优先级都触发计算
while(!ops.isEmpty() && prio.get(ch)<=prio.get(ops.peek())) {
calculate(ops, stk);
}
ops.push(ch);
i++;
}
}
while(!ops.isEmpty()) {
calculate(ops, stk);
}
return stk.peek();
}
private void calculate(Deque<Character> ops, Deque<Integer> stk) {
if(ops.isEmpty() && stk.size()<2) return;
char op = ops.pop();
int r = stk.pop();
int l = stk.pop();
int res = 0;
if(op=='*') res = l*r;
if(op=='/') res = l/r;
if(op=='+') res = l+r;
if(op=='-') res = l-r;
stk.push(res);
}
}
时间复杂度:;空间复杂度:
。