决战圣地玛丽乔亚重新归来之Day56--算法两道
回溯算法。
组合:
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
思路:如果用暴力解法,k=2,两层for循环就可以搞定,那么k=50要多少层for循环,是不合理的。
所以可以用递归的思路来完成,k的次数为递归的次数,在每次递归里进行循环。
回溯的三个步骤:
- 递归函数的返回值以及参数
- 回溯函数的终止条件
- 回溯函数的单层搜索过程
1.参数和返回值。 参数为n,k,startIndex(每次遍历的起始位置,防止重复) 由于是不可取重复次数,所以每个数只能取一次,第一次取1,下次取2,3,4
2.回溯的终止条件。 集合大小等于k
3.单层搜索过程:
for (int i = startIndex; i <= n; i++) { // 控制树的横向遍历
path.push_back(i); // 处理节点
backtracking(n, k, i + 1); // 递归:控制树的纵向遍历,注意下一层搜索要从i+1开始
path.pop_back(); // 回溯,撤销处理的节点
}
最终代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import java.util.ArrayList; import java.util.List; public class Combinations { public List<List<Integer>> combine( int n, int k) { List<List<Integer>> results = new ArrayList<>(); backtrack( new ArrayList<>(), 1 , n, k, results); return results; } private void backtrack(List<Integer> combination, int start, int n, int k, List<List<Integer>> results) { if (combination.size() == k) { results.add( new ArrayList<>(combination)); return ; } for ( int i = start; i <= n; i++) { combination.add(i); backtrack(combination, i + 1 , n, k, results); combination.remove(combination.size() - 1 ); } } public static void main(String[] args) { int n = 4 ; int k = 2 ; Combinations combinations = new Combinations(); List<List<Integer>> result = combinations.combine(n, k); for (List<Integer> combination : result) { System.out.println(combination); } } } |
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!