题目:
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
示例 :
输入: candidates =[2,3,6,7],
target =7
输出: [[7],[2,2,3]]
思路:
还是回溯法的思路,熟练地掌握回溯剪枝的模板之后,可以跳过一些无意义的重复。提高效率。
具体见代码及注释。
复杂度:
时间:O((n^2)。
空间:复杂度O(n)。
代码:
public List<List<Integer>> combinationSum(int[] candidates, int target) {
//最终返回的结果集合
List<List<Integer>> res = new ArrayList<List<Integer>>();
//每个符合条件的组合
List<Integer> cur = new ArrayList<Integer>();
//调用dfs()方法
dfs(candidates, target, res, cur, 0);
return res;
}
public void dfs(int[] candidates, int target, List<List<Integer>> res, List<Integer> cur, int idx) {
if (idx == candidates.length) {
return;
}
//如果当前的目标值为0,说明找到了一组组合,添加
if (target == 0) {
ans.add(new ArrayList<Integer>(cur));
return;
}
// 直接跳过,跳到candidates最后一个数开始
dfs(candidates, target, res, cur, idx + 1);
// 选择当前数
if (target - candidates[idx] >= 0) {
//把当前数加入到cur集合中
cur.add(candidates[idx]);
//结果自然要减去已经入集合的,然后再dfs();
dfs(candidates, target - candidates[idx], res, cur, idx);
//把cur里的最后一个移除
cur.remove(cur.size() - 1);
}
}