基础想法,遇到乘除就直接算,遇到加减需要把之后的所有乘除算完再加减。
一开始想用回溯的思想,每次遇到加减就进入下一层,在下一层中遇到加减就返回,尝试了一下太难实现了
然后,类似于字符串计算的题目基本都会想到使用堆栈。我们需要把所有乘除算完之后,再从头计算加减,因此我们建立两个双端队列(因为最后算还是要从头开始),一个存乘除计算后的数字,一个存 加减符号。遍历思想是,判断符号,如果是乘除就从数字队列取出最上面的那个数算完再放回去,如果是加减就直接把数字和符号都放进去。 最后再遍历一编两个队列把他们都组合起来得到最终的答案。
优化:(9ms)
- 不用两个队列,如果是减法我们只需要把那个数变成负数就可以,这样所有的运算符都是加号(8ms)
- 不用使用系统集合,系统提供的集合在存取的过程中还是太慢了,我们只要自定义一个数组,和下标,来模拟栈(6ms)
- 因为优化1,所以不需要从头开始计算,从尾巴开始也可以,即不用双端的思想,只要后进先出一个个取出就可以了(3ms)
- 比最快的还是慢了3ms,在于我把去除空格的操作独立了出来,导致多遍历了一遍。最主要的原因是我的写法在过程中不好判断空格,写法不好
自己的(3ms)
class Solution {
public int calculate(String s) {
StringBuilder ss = new StringBuilder(s);
for(int i = 0; i < ss.length();i++)
if(ss.charAt(i) == ' '){
ss.delete(i,i + 1);
i--;
}
s = ss.toString();
int index = 0;
int ans = 0;
int[] q = new int[s.length()];
int num = 0;
while(index < s.length() && s.charAt(index) >= '0' && s.charAt(index) <= '9'){
ans *= 10;
ans += s.charAt(index) - '0';
index ++;
}
q[num] = ans;
while(index < s.length()){
char c= s.charAt(index ++);
int t1 = 0;
while(index < s.length() && s.charAt(index) >= '0' && s.charAt(index) <= '9'){
t1 *= 10;
t1 += s.charAt(index) - '0';
index ++;
}
int n;
switch(c){
case '/':
q[num] /= t1;
break;
case '*':
q[num] *= t1;
break;
case '-':
q[++num] = -1 * t1;
break;
case '+':
q[++num] = t1;
break;
}
}
ans = 0;
while(num >= 0){
ans += q[num --];
}
return ans;
}
}
0ms
class Solution {
public int calculate(String s) {
if(s.length() >= 209079){return 199;}
int[] numStack = new int[s.length()];
int index = -1;
char symbol = '+', c;
int num = 0, ans = 0;
for (int i = 0; i <s.length(); i++) {
c = s.charAt(i);
if (c >= '0' && c <= '9') {
num = num * 10 + c - '0';
}
if (c < '0' && c != ' ' || i == s.length() - 1) {
switch (symbol) {
case '+':
numStack[++index] = num;
break;
case '-':
numStack[++index] = -num;
break;
case '*':
numStack[index] *= num;
break;
case '/':
numStack[index] /= num;
break;
default:
break;
}
symbol = c;
num = 0;
}
}
while (index > -1) {
ans += numStack[index--];
}
return ans;
}
}