一个网友回复:
回溯法的模板很好记,但是何时用start变量,何时用visited数组呢? 当为组合问题,即[a, b]与[b, a]等价,用start变量,当为排列问题,即[a, b]与[b, a]不等价,用visited数组
回溯算法模板
void backtracking(参数){
if(终止条件){
收集结果;
return;
}
for(遍历元素){
处理节点;
递归函数;
回溯操作;
}
return;
}
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
List<Integer> tem = new ArrayList<>();
int[] visited = new int[nums.length];
dfs(res,tem,visited,nums);
return res;
}
public void dfs(List<List<Integer>> res,List<Integer> tem,int[] visited,int[] nums){
if(tem.size()==nums.length){
res.add(new ArrayList(tem));
return;
}
for(int i=0;i<nums.length;i++){
if(visited[i]==1) continue;
visited[i] = 1;
tem.add(nums[i]);
dfs(res,tem,visited,nums);
visited[i]=0;
tem.remove(tem.size()-1);
}
}
}
写了两种,没啥区别
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> temp = new ArrayList<>();
Arrays.sort(candidates);
dfs(candidates,target,0,temp);
return res;
}
public void dfs(int[] candidates,int target,int start,List<Integer> temp){
if(target==0){
res.add(new ArrayList<>(temp));
return;
}
if(target<0) return;
for(int i=start;i<candidates.length;i++){
temp.add(candidates[i]);
dfs(candidates,target-candidates[i],i,temp);
temp.remove(temp.size()-1);
}
}
}
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> temp = new ArrayList<>();
Arrays.sort(candidates);
dfs(candidates,target,0,temp);
return res;
}
public void dfs(int[] candidates,int target,int start,List<Integer> temp){
if(target==0){
res.add(new ArrayList<>(temp));
return;
}
if(target<0) return;
for(int i=start;i<candidates.length;i++){
temp.add(candidates[i]);
dfs(candidates,target-candidates[i],i,temp);
temp.remove(temp.size()-1);
}
}
}