- 链接:https://leetcode.cn/problems/combination-sum/description/
版本一 #
按照回溯的板子写了一版代码
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
int n = candidates.length;
dfs(res, candidates, n, 0, target, new ArrayList<Integer>());
return res;
}
public void dfs(List<List<Integer>> res, int[] candidates, int n, int now, int target, ArrayList<Integer> temp) {
if(now == target) {
res.add(new ArrayList<>(temp));
return;
}
if(now > target) {
return;
}
for(int i = begin; i < n;i++) {
temp.add(candidates[i]);
dfs(res, candidates, n, now+candidates[i], target, temp);
temp.remove(temp.size()-1);
}
}
}
这版本代码会有重复,怎么避免这个问题呢?
版本二 #
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
int n = candidates.length;
dfs(res, candidates, 0, n, 0, target, new ArrayList<Integer>());
return res;
}
public void dfs(List<List<Integer>> res, int[] candidates, int begin, int n, int now, int target, ArrayList<Integer> temp) {
if(now == target) {
res.add(new ArrayList<>(temp));
return;
}
if(now > target) {
return;
}
for(int i = begin; i < n;i++) {
temp.add(candidates[i]);
dfs(res, candidates, i, n, now+candidates[i], target, temp);
temp.remove(temp.size()-1);
}
}
}
版本三 剪枝 #
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
int len = candidates.length;
List<List<Integer>> res = new ArrayList<>();
if (len == 0) {
return res;
}
// 排序是剪枝的前提
Arrays.sort(candidates);
Deque<Integer> path = new ArrayDeque<>();
dfs(candidates, 0, len, target, path, res);
return res;
}
private void dfs(int[] candidates, int begin, int len, int target, Deque<Integer> path, List<List<Integer>> res) {
// 由于进入更深层的时候,小于 0 的部分被剪枝,因此递归终止条件值只判断等于 0 的情况
if (target == 0) {
res.add(new ArrayList<>(path));
return;
}
for (int i = begin; i < len; i++) {
// 重点理解这里剪枝,前提是候选数组已经有序,
if (target - candidates[i] < 0) {
break;
}
path.addLast(candidates[i]);
dfs(candidates, i, len, target - candidates[i], path, res);
path.removeLast();
}
}
}