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]
[分析] 这题参考 https://leetcode.com/discuss/48488/c-4ms-recursive-method 。 思路类似Unique Binary Search Trees II,以某个运算符为分界线,递归计算左右两边可能的值,然后根据当前运算符归并结果。纯粹的递归含有冗余计算,可同时保留中间结果来提高效率。
public class Solution { // method 2: dp public List<Integer> diffWaysToCompute(String input) { HashMap<String, List<Integer>> dpMap = new HashMap<String, List<Integer>>(); return computeWithDP(input, dpMap); } public List<Integer> computeWithDP(String input, HashMap<String, List<Integer>> dpMap) { List<Integer> result = new ArrayList<Integer>(); if (input == null || input.length() == 0) return result; int N = input.length(); for (int i = 0; i < N; i++) { char c = input.charAt(i); if (c == '+' || c == '-' || c == '*') { String leftSubStr = input.substring(0, i); String rightSubStr = input.substring(i + 1, N); List<Integer> left = dpMap.get(leftSubStr); if (left == null) left = computeWithDP(leftSubStr, dpMap); List<Integer> right = dpMap.get(rightSubStr); if (right == null) right = computeWithDP(rightSubStr, dpMap); for (int op1: left) { for (int op2: right) { if (c == '+') result.add(op1 + op2); else if (c == '-') result.add(op1 - op2); else result.add(op1 * op2); } } } } if (result.isEmpty()) result.add(Integer.parseInt(input)); dpMap.put(input, result); return result; } // method 1: recursive public List<Integer> diffWaysToCompute1(String input) { List<Integer> result = new ArrayList<Integer>(); if (input == null || input.length() == 0) return result; int N = input.length(); for (int i = 0; i < N; i++) { char c = input.charAt(i); if (c == '+' || c == '-' || c == '*') { List<Integer> left = diffWaysToCompute(input.substring(0, i)); List<Integer> right = diffWaysToCompute(input.substring(i + 1, N)); for (int op1 : left) { for (int op2 : right) { if (c == '+') result.add(op1 + op2); else if (c == '-') result.add(op1 - op2); else result.add(op1 * op2); } } } } // if the string contains only number if (result.isEmpty()) result.add(Integer.parseInt(input)); return result; } }