力扣算法:组合总和

原题链接:https://leetcode-cn.com/problems/combination-sum

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。 

解题思路:

  这题开始就打算用回溯的思路完成。设定一个存放结果的list ,和sum存放当前list 的总和,通过回溯实现。代码如下:

public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> daan = new ArrayList<>();
        backtrack(result,candidates,target,daan,0);
        return result;
    }

    //回溯算法
    public void backtrack(List<List<Integer>> result,int[] candidates, int target,List<Integer> daan,int sum  ){
        if(sum == target){
            result.add(new ArrayList<Integer>(daan));
            return;
        }
        if(sum>target){
            return;
        }
        
        for(int i=0;i<candidates.length;i++){
            if(sum+candidates[i]<=target){
                daan.add(candidates[i]);
                backtrack(result,candidates,target,daan,sum+candidates[i]);
                daan.remove(daan.size()-1);
            }

        }

    }

开始我用的这种方式,但是经过测试发现其中包括了重复的子集。

所以,需要进一步修改,需要在回溯的过程中增加一个参数,即为查找的起点,完整代码如下

public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> daan = new ArrayList<>();
        backtrack(result,candidates,target,daan,0,0);
        return result;
    }

    //回溯算法
    public void backtrack(List<List<Integer>> result,int[] candidates, int target,List<Integer> daan,int sum ,int start  ){  //增加起点标记
        if(sum == target){
            result.add(new ArrayList<Integer>(daan));
            return;
        }
        if(sum>target){
            return;
        }

        for(int i=start;i<candidates.length;i++){   //修改了循环的起点
            if(sum+candidates[i]<=target){
                daan.add(candidates[i]);
                backtrack(result,candidates,target,daan,sum+candidates[i],i);  //因为数字可以重复使用,起点为 i 
                daan.remove(daan.size()-1);
            }

        }

    }
原文地址:https://www.cnblogs.com/wys-373/p/13697671.html