package leetcode;
import java.util.ArrayList;
import java.util.List;
public class Solution241 extends Solution {
@Override
public void test() {
// String input = "2-1-1";
String input = "2*3-4-5";
System.out.println(diffWaysToCompute(input));
}
public List<Integer> diffWaysToCompute(String input) {
/*
想法一:
最开始的想法是迭代的计算每个符号的位置的值,即将第i个符号处两边的数字进行运算,
并将运算后得到的值替代原先i个位置,且将i-1和i+1处的数字删去,这样就得到一个新
的计算公式,然后进入下一次迭代。
但这么做会出现重复的情况,如:2*3-4*5,正常答案是[-34, -14,-10,-10,10],但
迭代后会出现两个-14,因为((2*3)-(4*5))会出现两次,分别为以2*3中的乘号为迭代
起点和4*5中的乘号为迭代起点。
所以该方法不可行。
想法二:
构造表达式树,以每个符号为树的根节点,左子树和右子树分别返回各自子表达式的所有可
能情况的计算结果,然后根据根节点的符号组合左子树和右子树的结果。
*/
if (input.length() < 3) {
ArrayList<Integer> tmp = new ArrayList<>();
if (input.contains("+") || input.contains("-") || input.contains("*")) {
return tmp;
} else {
tmp.add(Integer.valueOf(input));
return tmp;
}
}
List<Integer> nums = new ArrayList<>(); //用来存放数字 [2,3,4,5]
List<Character> operator = new ArrayList<>();//用来存放运算符 [*,-,*]
int digit = 0;
for(char c : input.toCharArray()){
if (c >= '0' && c <= '9') {
digit = digit * 10 + (c - '0');
} else {
nums.add(digit);
digit = 0;
operator.add(c);
}
}
nums.add(digit);
return helper(nums, operator, 0, operator.size()-1);
}
private List<Integer> helper(List<Integer> nums, List<Character> operator, int start, int end){
if (end <= start) {
// 如果只有一个运算符,就计算运算结果,并返回
int t = operator(operator.get(start), nums.get(start), nums.get(end+1));
List<Integer> res = new ArrayList<>();
res.add(t);
return res;
}
List<Integer> res = new ArrayList<>();
List<Integer> left = null, right = null;
for(int i=start; i<=end; i++){
if (i == start) {
left = new ArrayList<>();
left.add(nums.get(start));
} else {
left = helper(nums, operator, start, i-1);
}
if (i == end) {
right = new ArrayList<>();
right.add(nums.get(end+1));
} else {
right = helper(nums, operator, i + 1, end);
}
for (Integer l : left) {
for (Integer r : right) {
res.add(operator(operator.get(i), l, r));
}
}
}
return res;
}
private int operator(char operator, int a, int b){
switch (operator){
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return -1;
}
}