39. 组合总和(无重复数字)

组合问题的变形

class Solution {
    LinkedList<List<Integer>> ans=new LinkedList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
      dfs(candidates,0,target);
      return ans;
    }
    void dfs(int[] candidates,int begin,int target){
      if(target==0){
          ans.add(new LinkedList(path));
          return;
      }
      if(target<0)return;//如果有负数怎么结束递归
      for(int i=begin;i<candidates.length;i++){
         path.add(candidates[i]);
         dfs(candidates,i,target-candidates[i]);//因为可以重复选取,所以下一次还可以从当前i的位置开始
         path.removeLast();
     }

    }
}

对每个数字,有选和不选两种选择。实际上面递归是多叉树,下面是二叉树。性能是差不多的.
下面这种begin标识用cur代替。

class Solution {
    LinkedList<List<Integer>> ans=new LinkedList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
      dfs(candidates,target,0);
      return ans;
    }
    void dfs(int[] candidates,int target,int cur){
      if(target==0){
          ans.add(new LinkedList(path));
          return;
      }
      if(target<0)return;//如果有负数怎么结束递归
      if(cur==candidates.length)return;
      //不选当前元素
      dfs(candidates,target,cur+1);
      //选当前元素
      path.add(candidates[cur]);
      dfs(candidates,target-candidates[cur],cur);//下次还可以选当前元素
      path.removeLast();

      


    }
}
posted @ 2021-04-24 21:01  wsshub  阅读(70)  评论(0)    收藏  举报