给定一个正确的表达式(不用担忧不规范的输入),好比2-1-1, 经过在不一样位置添加左右括号,改变求值的优先级顺序,求出全部的这些值;java
Example 1算法
Input: "2-1-1"
.spa
((2-1)-1) = 0 (2-(1-1)) = 2
Output: [0, 2]
code
Example 2orm
Input: "2*3-4*5"
递归
(2*(3-(4*5))) = -34 ((2*3)-(4*5)) = -14 ((2*(3-4))*5) = -10 (2*((3-4)*5)) = -10 (((2*3)-4)*5) = 10
Output: [-34, -14, -10, -10, 10]
get
这个题目应该没有便捷的解法,只能所有的都尝试一遍;固然仅仅须要暴力的枚举一遍,也没有什么有趣的地方,我以为有趣的地方体如今下面两点:input
1. 这个题目能够用递归的方法求解,由于,假设遇到某个操做符,若是知道了左边的结果,再计算出右边的结果,那么只要把左右两边的结果合并起来,就能够了;it
2. 固然若是直接按照递归去作,会出现一个问题,(大概会超时,我没有提交这样的代码);假设在获得了某个操做符两边的结果后,到了下一个操做符,递归计算的时候,任然会须要前面一个操做符(左边的)的结果,因此必需要把已经计算过的结果要cache起来;io
最后的代码以下:
private final static long base = 100001; private Map<Long, List<Integer>> cache = new HashMap<>(); private List<Integer> diffWaysToCompute(char[] cs, int start, int end) { long key = base * start + end; if (cache.containsKey(key)) { return cache.get(key); } boolean isNumber = true; for (int i = start; i < end; i++) { if (isOperator(cs[i])) { isNumber = false; break; } } List<Integer> result = new ArrayList<>(); if (isNumber) { result.addAll(toNum(cs, start, end)); } else { for (int i = start; i < end; i++) { if (isOperator(cs[i])) { List<Integer> prev = diffWaysToCompute(cs, start, i); List<Integer> suff = diffWaysToCompute(cs, i + 1, end); result.addAll(combineResult(prev, suff, cs[i])); } } return result; } cache.put(key, result); return result; } private List<Integer> combineResult(List<Integer> prev, List<Integer> suff, char op) { List<Integer> result = new ArrayList<>(); for (int x : prev) { for (int y : suff) { result.add(calculate(x, y, op)); } } return result; } private int calculate(int x, int y, char op) { switch (op) { case '+': return x + y; case '-': return x - y; case '*': return x * y; } return 0; } private List<Integer> toNum(char[] cs, int start, int end) { int num = 0; for (int i = start; i < end; i++) { if (cs[i] == ' ') { continue; } num = num * 10 + (cs[i] - '0'); } List<Integer> result = new ArrayList<>(1); result.add(num); return result; } private boolean isOperator(char c) { return c == '+' || c == '-' || c == '*'; } public List<Integer> diffWaysToCompute(String input) { return diffWaysToCompute(input.toCharArray(), 0, input.length()); } public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.diffWaysToCompute("2-4").stream().map(x -> "" + x).collect(Collectors.joining(","))); }
再仔细想一想,这种须要cache以前结果的递归算法,应该是能够用动态规划的方式表达出来的。惋惜我不擅长动态规划,就不费脑力了~~~