39. Combination Sum

     /*
      * 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);
         }
     }
原文地址:https://www.cnblogs.com/zmyvszk/p/5457911.html