Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *. Example 1 Input: "2-1-1". ((2-1)-1) = 0 (2-(1-1)) = 2 Output: [0, 2] Example 2 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]
如今有一個字符串形式的算式,求該算式在任意位置加上任意數量的括號後可以得出的全部可能的值。git
這是經典的分治法。咱們將算式從一個操做符的位置分割開,並分別得出左邊和右邊算式全部可能的值。再將左右的值分別按照操做符進行計算。這裏經過遞歸實現。面試
public List<Integer> diffWaysToCompute(String input) { return diffWaysToCompute(input, 0, input.length()); } public List<Integer> diffWaysToCompute(String input, int startIndex, int endIndex){ boolean isDigit = true; List<Integer> result = new ArrayList<Integer>(); for(int i = startIndex ; i<endIndex ; i++){ char cur = input.charAt(i); if(cur == '+' || cur == '-' || cur=='*' ){ isDigit = false; List<Integer> leftValue = diffWaysToCompute(input, startIndex, i); List<Integer> rightValue = diffWaysToCompute(input, i+1, endIndex); result.addAll(compute(leftValue, rightValue,cur)); } } if(isDigit){ result.add(Integer.parseInt(input.substring(startIndex, endIndex))); } return result; } public List<Integer> compute(List<Integer> leftValue, List<Integer> rightValue, char operator){ switch(operator){ case '+' : return add(leftValue, rightValue); case '-' : return minus(leftValue, rightValue); case '*' : return multiply(leftValue, rightValue); } return new ArrayList<>(); } public List<Integer> add(List<Integer> leftValue, List<Integer> rightValue){ List<Integer> result = new ArrayList<Integer>(); for(int left : leftValue){ for(int right : rightValue){ result.add(left + right); } } return result; } public List<Integer> minus(List<Integer> leftValue, List<Integer> rightValue){ List<Integer> result = new ArrayList<Integer>(); for(int left : leftValue){ for(int right : rightValue){ result.add(left - right); } } return result; } public List<Integer> multiply(List<Integer> leftValue, List<Integer> rightValue){ List<Integer> result = new ArrayList<Integer>(); for(int left : leftValue){ for(int right : rightValue){ result.add(left * right); } } return result; }
提升性能的方法是經過Map實現緩存。將已經遍歷過的結果存入緩存中,若是碰到重複的計算式,就能夠直接獲取其全部可能的值。算法
Map<String, List<Integer>> cache = new HashMap<String, List<Integer>>(); public List<Integer> diffWaysToCompute_withCache(String input){ if(cache.containsKey(input)) return cache.get(input); List<Integer> result = new ArrayList<Integer>(); boolean isDigit = true; for(int i = 0 ; i<input.length() ; i++){ int cur = input.charAt(i); if(cur == '+' || cur == '-' || cur == '*'){ isDigit = false; List<Integer> leftValues = diffWaysToCompute_withCache(input.substring(0, i)); List<Integer> rightValues = diffWaysToCompute_withCache(input.substring(i+1)); for(Integer left : leftValues){ for(Integer right : rightValues){ switch(cur){ case '+' : result.add(left + right); break; case '-' : result.add(left - right); break; case '*' : result.add(left * right); break; } } } } } if(isDigit){ result.add(Integer.parseInt(input));} cache.put(input, result); return result; }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~緩存