将问题递归成子问题
对于a * b - c
可以先以运算符为分界
比如以-号为分界
-号左侧a * b
-号右侧c
所以总的结果中包含(a * b) - c
a * b的结果同样递归
以此类推
在运算过程中有大量的中间态结果是重复需要的,所以用记忆化dfs的方式即可
class Solution {
List<Integer> elements = new ArrayList<>();
int n;
// dfs[i][j] 是 从i到j 的所有结果的集合
List<Integer>[][] dfs;
public List<Integer> diffWaysToCompute(String expression) {
int len = expression.length();
int temp = 0;
for (int i = 0; i < len; i++) {
char c = expression.charAt(i);
if (!Character.isDigit(c)) {
if (c == '+') {
elements.add(-1);
} else if (c == '-') {
elements.add(-2);
} else if (c == '*') {
elements.add(-3);
}
} else {
temp *= 10;
temp += Integer.parseInt(String.valueOf(c));
if (i == len - 1 || !Character.isDigit(expression.charAt(i + 1))) {
elements.add(temp);
temp = 0;
}
}
}
n = elements.size();
dfs = new List[n][n];
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
dfs[i][j] = new ArrayList<>();
}
dfs[i][i].add(elements.get(i));
}
return dfs(0, n - 1);
}
List<Integer> dfs(int start, int end) {
if (dfs[start][end].isEmpty()) {
for (int i = start + 1; i <= end; i++) {
addResult(start, end, elements.get(i), i);
}
}
return dfs[start][end];
}
void addResult(int start, int end, int number, int index) {
if (elements.get(index) < 0) {
List<Integer> left = dfs(start, index - 1);
List<Integer> right = dfs(index + 1, end);
for (Integer l : left) {
for (Integer r : right) {
if (number == -1) {
dfs[start][end].add(l + r);
} else if (number == -2) {
dfs[start][end].add(l - r);
} else if (number == -3) {
dfs[start][end].add(l * r);
}
}
}
}
}
}