1.<tag-回溯和组合及其剪枝>lt.77.组合 +剪枝
回溯模板
让一让了啊, 回溯模板又来了;
// 路径path, 是回溯递归树中每一条从根节点到叶子结点的路径
//选择列表, 是回溯需要的一个基础数组/列表
//1. 递归函数
public void backTracking(路径, 选择列表){
//2. 递归出口
//当我们走完递归树中的一条路径时, 就可以向上返回一层递归,
if(递归结束条件: path.size() == 基础数组长度){
回溯结果result.add(一条结果集 path);
return;
}
//3. 单层递归逻辑
for(选择 in 选择列表){
做选择, 把节点添加到path: path.add(节点);
backTracking(路径, 选择列表);
撤销选择, 移除当前层的节点, 返回到上一层: path.remove(path.size() - 1);
}
}
lt.77.组合
摘自: 代码随想录, 卡子哥讲的还是相当不错的!
[思路分析]
利用递归三部曲来解决回溯问题
[未优化的代码一]
class Solution {
List<List<Integer>> lists = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
//n是取值的范围, 即树的宽度
//k是子结果的个数, 即树的深度
backTracking(n, k, 1);
return lists;
}
//1. 递归函数:
//参数: //n是取值的范围, 即树的宽度
//k是子结果的个数, 即树的深度
//可以看到, startIndex是去重的关键
public void backTracking(int n, int k, int startIndex){
//2. 递归出口: 当一条子路径遍历完了, 就可以满足出口
if(k == path.size()){
lists.add(new ArrayList<>(path));
return;
}
//3. 单层递归逻辑
for(int i = startIndex; i <= n; i++){
path.add(i);
backTracking(n, k, i + 1);
path.remove(path.size() - 1);
}
}
}
[回溯的剪枝]
[剪枝优化的代码二]
class Solution {
List<List<Integer>> lists = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
//n是取值的范围, 即树的宽度
//k是子结果的个数, 即树的深度
backTracking(n, k, 1);
return lists;
}
//1. 递归函数:
//参数: //n是取值的范围, 即树的宽度
//k是子结果的个数, 即树的深度
//可以看到, startIndex是去重的关键
public void backTracking(int n, int k, int startIndex){
//2. 递归出口: 当一条子路径遍历完了, 就可以满足出口
if(k == path.size()){
lists.add(new ArrayList<>(path));
return;
}
//3. 单层递归逻辑
for(int i = startIndex; i <= n - (k - path.size()) + 1; i++){
path.add(i);
backTracking(n, k, i + 1);
path.remove(path.size() - 1);
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)