标准的回溯方法模板题,使用回溯三部曲可以解决问题
回溯三部曲:
- 递归函数参数
- 递归终止条件
- 单层搜索逻辑
### 解题思路
此处撰写解题思路
### 代码
```java
class Solution {
List<Integer> path = new LinkedList<>();
List<List<Integer>> result= new LinkedList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
callback(candidates, target, 0, 0);
return result;
}
int sum = 0;
private void callback(int[] candidates, int target, int sum, int index) {
if(sum > target) {
// 超过指定的目标数字
return;
}
if(sum == target) {
result.add(new LinkedList<>(path));
return;
}
// 单层循环逻辑
for (int i = index; i <= candidates.length - 1; i++) {
sum += candidates[i];
path.add(candidates[i]);
// 这里传递索引的时候,不需要加1后再传值,因为数字是可以重复使用的,而不是组合问题。
// 组合问题不能使用重复的元素,这里可以使用重复的元素
callback(candidates, target, sum, i);
// 回溯,移除末尾的元素
sum -= candidates[i];
path.remove(path.size() - 1);
}
}
}
// 剪枝优化
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates); // 先进行排序
backtracking(res, new ArrayList<>(), candidates, target, 0, 0);
return res;
}
public void backtracking(List<List<Integer>> res, List<Integer> path, int[] candidates, int target, int sum, int idx) {
// 找到了数字和为 target 的组合
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = idx; i < candidates.length; i++) {
// 如果 sum + candidates[i] > target 就终止遍历
if (sum + candidates[i] > target) break;
path.add(candidates[i]);
backtracking(res, path, candidates, target, sum + candidates[i], i);
path.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素
}
}
}