LeetCode39
原题如下:LeetCode39
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
首先看题目又如下几个关键点:
- 组合
- 无重复元素
- 无限制重复读取
从上面的三个信息中就可以读取到如下信息:
- [1,2,3]和[2,1,3]其实是一个组合
- 无重复元素则代表无需进行重复判断
- 在遍历的时候需要重复的进行一个元素进行累加
所以可以先写出如下结构代码:
private void backtracking(int[] candidates, int target,List<Integer> list,int sum,int currIndex) {
for(int i = currIndex; i < candidates.length; i++){
int total = sum + candidates[i];
if(total > target){
return;
}
list.add(candidates[i]);
backtracking(candidates, target, list,total,i);
list.remove(list.size() - 1);
}
}
看这个递归,应该注意到 currIndex 这个变量,这个其实就是控制重复添加的下标,考虑如下数组:
[1,2,3,4,5]
如果target 是6,那么按照这个递归,首先List的元素是[1,1,1,1,1,1],然后此时在循环里面添加一个 1
的时候,total 就为 7 ,所以直接 return。
而一旦递归开始回溯的时候,list 的最后一个元素就会被删除,变成了[1,1,1,1,1],此时 i 就变成了 1,所以 此时 list 就是 [1,1,1,1,2]
依次类推即可。
最终的代码如下:
class Solution {
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
backtracking(candidates,target,new ArrayList<>(),0,0);
return result;
}
private void backtracking(int[] candidates, int target,List<Integer> list,int sum,int currIndex) {
if(sum == target){
result.add(new ArrayList<>(list));
return;
}
if(sum > target){
return;
}
for(int i = currIndex; i < candidates.length; i++){
int total = sum + candidates[i];
if(total > target){
return;
}
list.add(candidates[i]);
backtracking(candidates, target, list,total,i);
list.remove(list.size() - 1);
}
}
}