题目:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例:
输入:candidates =[2,3,6,7],
target =7
, 所求解集为: [ [7], [2,2,3] ]
解题思路:回溯算法
注意:for循环中的dfs,传参数传i,不能传cur或者cur+1这些。
如果不设置cur,第一个解是2,2,3。第二个解是3,2,2。这样就重复了。
所以,我们需要遍历第一次遍历candidates的第一个元素得到2,2,3的之后,第二次3开头的时候直接从3后遍历,不要再找2了。
如果传i的话,递归得到第一种结果2,2,3之后i+1就变成了元素3的位置,并且for循环从3开始扫描,不会出现重复的现象了。
代码
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if (candidates.length == 0) return res;
List<Integer> path = new ArrayList<>();
dfs(candidates,target,path,res,0);
return res;
}
private static void dfs(int[] candidates, int target, List<Integer> path, List<List<Integer>> res,int cur) {
if (target == 0){
res.add(new ArrayList<>(path));
return ;
}
for (int i = cur; i < candidates.length; i++) {
if (candidates[i] <= target){
path.add(candidates[i]);
target -=candidates[i];
dfs(candidates,target,path,res,i);
path.remove(path.size()-1);
target += candidates[i];
}
}
}