中国住房和城乡建设网网站学习网站大全
LC77. 组合
- 题目要求
- (一)回溯
- 1. 解决思路
- 2. 具体步骤
- 3. 代码实现
- 4. 复杂度分析
- 5. 示例解释
- 示例 1:
- 示例 2:
- 6. 总结
LC77. 组合
题目要求

(一)回溯
要解决这个问题,我们需要生成从 [1, n] 范围内选择 k 个数的所有可能组合。组合的顺序不重要,即 [1, 2] 和 [2, 1] 被视为同一个组合。
1. 解决思路
我们可以使用回溯法(Backtracking)来生成所有可能的组合。回溯法是一种通过递归遍历所有可能解的方法,适用于组合、排列等问题。
2. 具体步骤
-
递归函数设计:
- 定义一个递归函数
backtrack(start, path),其中:start表示当前可以选择的起始数字。path是当前已经选择的数字组合。
- 如果
path的长度等于k,说明已经找到一个有效的组合,将其加入结果集。 - 否则,从
start开始遍历到n,依次选择数字并递归调用。
- 定义一个递归函数
-
剪枝优化:
- 在递归过程中,如果剩余的数字不足以填满
k个数的组合,可以直接剪枝,避免无效递归。
- 在递归过程中,如果剩余的数字不足以填满
-
初始化调用:
- 从
1开始调用递归函数,初始path为空。
- 从
3. 代码实现
def combine(n, k):def backtrack(start, path):# 如果当前路径长度等于 k,加入结果集if len(path) == k:result.append(path.copy())return# 遍历可能的数字for i in range(start, n + 1):path.append(i) # 选择当前数字backtrack(i + 1, path) # 递归选择下一个数字path.pop() # 撤销选择(回溯)result = []backtrack(1, [])return result
4. 复杂度分析
- 时间复杂度:O(C(n, k) * k),其中 C(n, k) 是组合数,表示从
n个数中选k个数的组合数。每个组合需要 O(k) 的时间来复制到结果集中。 - 空间复杂度:O(k),递归栈的深度为
k。
5. 示例解释
示例 1:
输入:n = 4, k = 2
- 调用
backtrack(1, []),开始递归:- 选择
1,递归调用backtrack(2, [1]):- 选择
2,得到组合[1, 2]。 - 选择
3,得到组合[1, 3]。 - 选择
4,得到组合[1, 4]。
- 选择
- 选择
2,递归调用backtrack(3, [2]):- 选择
3,得到组合[2, 3]。 - 选择
4,得到组合[2, 4]。
- 选择
- 选择
3,递归调用backtrack(4, [3]):- 选择
4,得到组合[3, 4]。
- 选择
- 选择
4,递归调用backtrack(5, [4]),不满足条件,直接返回。
- 选择
- 最终结果为
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]。
示例 2:
输入:n = 1, k = 1
- 调用
backtrack(1, []),选择1,得到组合[1]。 - 最终结果为
[[1]]。
6. 总结
通过回溯法,我们可以高效地生成所有可能的组合。递归函数的设计和剪枝优化是解决问题的关键。
