https://oj.leetcode.com/problems/combination-sum/
http://fisherlei.blogspot.com/2013/01/leetcode-combination-sum-solution.html
http://blog.csdn.net/linhuanmars/article/details/20828631
public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { // Solution A // return combinationSum_Coin(candidates, target); // Solution B return combinationSum_DP(candidates, target); } ///////////////////////////// // Solution B: DP // private List<List<Integer>> combinationSum_DP(int[] candidates, int target) { List<List<Integer>> result = new ArrayList<>(); if (candidates == null || candidates.length == 0) return result; // Sort Arrays.sort(candidates); combinationSum_DP_help(candidates, 0, target, new ArrayList<Integer>(), result); return result; } private void combinationSum_DP_help(int[] c, int start, int t, List<Integer> items, List<List<Integer>> result) { if (t < 0) return; if (t == 0) { // A result found result.add(new ArrayList<Integer>(items)); } for (int i = start ; i < c.length ; i ++) { // 由于输入数组中的元素可以重复使用, // 所以在下一次迭代中,start 仍然是 i, 而不是i+1 // 这是和 Combination Sum II 的区别 // // 所以当i和i-1 一样时,我们跳过这 组 迭代 // // 否则,输入数组可以进行预处理消除重复,则不需要这个if逻辑 if (i > 0 && c[i] == c[i - 1]) continue; items.add(c[i]); combinationSum_DP_help(c, i, t - c[i], items, result); items.remove(items.size() - 1); } } ///////////////////////////// // Solution A: Coin // private List<List<Integer>> combinationSum_Coin(int[] candidates, int target) { if (candidates == null || candidates.length == 0) return Collections.emptyList(); // Invalid input. // The coin problems. // Since same number can be used multiple times. // Let sort it and remove dupes. List<Integer> c = sortAndDedupe(candidates); Set<List<Integer>> result = new HashSet<>(); sum(c, target, 0, new ArrayList<Integer>(), result); return new ArrayList<>(result); } private void sum(List<Integer> c, int t, int sumsofar, List<Integer> nums, Set<List<Integer>> result) { if (sumsofar > t) return; if (sumsofar == t) { // A solution found Collections.sort(nums); result.add(nums); return; } for (int i = c.size() - 1 ; i >= 0 ; i --) { int v = c.get(i); if (sumsofar + v <= t) { List<Integer> newnums = new ArrayList<>(nums); newnums.add(v); sum(c, t, sumsofar + v, newnums, result); } } } private List<Integer> sortAndDedupe(int[] c) { Set<Integer> set = new HashSet<>(); for (int i : c) { set.add(i); } List<Integer> toReturn = new ArrayList<>(set); Collections.sort(toReturn); return toReturn; } }