/* * 39. Combination Sum * 2016-5-3 by Mingyang * The same repeated number may be chosen from C unlimited number of times. * 注意在实现中for循环中第一步有一个判断,那个是为了去除重复元素产生重复结果的影响 * 因为在这里每个数可以重复使用,所以重复的元素也就没有作用了,所以应该跳过那层递归。 * 1.长度标准:无(固定) * 2.可选的范围:从start开始到最后一个数 * 3.往前走一步:temp加入这个数,remain再减去 * 4.后退一步:temp减去这个数 * 5.特别的case:剩下的小于0直接return * 6.关于重复:因为每个数可以用很多次。所以223时会出现重复,所以可以跳过第二个2. * 自己在做这一道题目的时候出现过一下问题: * 忘了Arrays.sort不是Array.sort * if (i > 0 && candidates[i] == candidates[i - 1])跳过重复那一步没有做 * 忘了加start,并且在下一层的时候start应该更新为i,新的起点,我错误的写成了start * 那么久意味着永远在start的这一个层面一直走 */ public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<List<Integer>>(); List<Integer> temp = new ArrayList<Integer>(); Arrays.sort(candidates); dfs(candidates, target, 0, temp, res); return res; } public void dfs(int[] candidates, int remain, int start,List<Integer> temp, List<List<Integer>> res) { if (remain == 0) { res.add(new ArrayList<Integer>(temp)); return; } if (remain < 0) return; for (int i = start; i < candidates.length; i++) { if (i > 0 && candidates[i] == candidates[i - 1]) // 这里就是跳过那个重复的元素,因为每次已经可以重复使用自己了,这一步很重要!!不过这里只要i大于0都比较 //但下面一个题目是大于start,本题大于0可以是因为已经重复使用自己,不必再使用下一个相同的值了 continue; temp.add(candidates[i]); dfs(candidates, remain - candidates[i], i, temp, res); temp.remove(temp.size() - 1); } }