前言
最近也是在学习回溯算法,在哔哩哔哩上看到了一个视频讲的很不错,就是集数有点少,这里把链接分享给你们。
一、回溯
回溯的基本概念这里就不再去讲述了,需要的可以自己去详细了解。
下面就是代码随想录总结的回溯题的模板,感觉跟着这个思路去做题,思路还是很清晰的。
解题:
void backtracking(参数 ) {
if(终止条件){
收集结果;
}
for(集合元素集){
处理节点;
递归函数 backtracking;
撤销操作;
}
}
二、组合数
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2
输出:
```c
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
示例 2:
输入:n = 1, k = 1
输出:[[1]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题代码
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res = new ArrayList<>();
Deque<Integer> path = new ArrayDeque<>();
backTrackint(n,k,1,path,res);
return res;
}
//回溯算法
//1.确定递归函数以及递归函数的返回值
//递归函数一般都是backTarcking,返回值一般都是void
public static void backTrackint(int n,int k,int start,Deque<Integer> path,List<List<Integer>> res){
//2.确定递归结束条件
if(path.size() == k){
//当队列的长度等于k的时候,说明有一个满足题意的组合,
//将这个组合加入res,并返回上一层递归
res.add(new ArrayList<>(path));
return;
}
//3.确定单层循环逻辑
//剪枝操作:当n - i不满足k时,就直接不用往下进行遍历
// i <= n - (k - path.size()) + 1;
for(int i = start; i <= n - (k - path.size()) + 1 ;i++){
//全排列,需要循环遍历每一个数
path.addLast(i);
backTrackint(n,k,i+1,path,res);
//回溯操作
path.removeLast();
}
}
}