今天将两道相似的题写下来,这两道题都用到了回溯的方法。
77 组合、
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
思路是看的iweiwei1419大神的。讲的比较透彻,在力扣的题解页面代码的剪枝方面讲解的同样透彻。
代码为:
public List> combine(int n, int k) {
List> res = new ArrayList<>();
if(n <= 0 || n < k)
return res;
Deque path = new ArrayDeque<>();
dfs(n,k,1,res,path);
return res;
}
public void dfs(int n, int k, int begin, List> res, Deque path){
if(path.size() == k){
res.add(new ArrayList<>(path));
return;
}
/*
搜索起点的上界 + 接下来要选择的元素个数 - 1 = n;
其中,接下来要选择的元素个数 = k - path.size(),整理得到:
搜索起点的上界 = n - (k - path.size()) + 1
*/
//for(int i = begin ; i <= n ; i++){
for(int i = begin ; i <= n-(k-path.size())+1 ; i++){
path.addLast(i);
dfs(n,k,i+1,res,path);
path.removeLast();
}
}
}
在看类似的39题,也是同样用的是回溯的思路,在剪枝方面还是借助了大佬的思路。
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
/**
* 39. 组合总和
* 与上面的一样利用回溯的解法
* @param args
*/
public List> combinationSum(int[] candidates, int target) {
List> res = new ArrayList<>();
Deque path = new ArrayDeque<>();
if(candidates.length < 0)
return res;
Arrays.sort(candidates); //剪枝,排序加强一些
backtrack(candidates,target,0,path,res);
return res;
}
public void backtrack(int[] candidates, int target, int begin, Deque path, List> res){
if(target < 0) //终止条件
return;
if(target == 0){ //终止条件
res.add(new ArrayList<>(path)); //存放结果
return;
}
for(int i = begin ; i < candidates.length ; i++){ //需要开始进行的点 ,,,,
//当target - candidates[i] < 0 就表示现在数之和已经大于目标值,就不用再往下进行了
if (target - candidates[i] < 0){
break;
}
path.addLast(candidates[i]); //回溯开始之前将数字加进去 //递归,处理节点;
backtrack(candidates,target-candidates[i],i,path,res); //进入回溯注意还要从i开始。判断是不是全是i还是有几个i
path.removeLast(); //回溯之后要回到原状态 // 回溯,撤销处理结果
}
}