描述
给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
示例 2:
输入:n = 1, k = 1 输出:[[1]]
提示:
1 <= n <= 20
1 <= k <= n
全组合代码
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
lis = []
for i in range(1,n+1):
lis.append(i)
result = list(combinations(lis,k))
return result
需要注意的细节:输出结果的格式是 [[],[].....],即 List[List[int]] ,故需要对全组合原始结果进行 list处理。
枚举下一个数选谁
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
ans = [] # 用于存储所有可能的组合结果
path = [] # 用于存储当前的组合路径
def dfs(i: int) -> None: # 定义深度优先搜索(DFS)函数,参数i表示当前搜索的起始位置
d = k - len(path) # 计算当前还需要选取多少个元素才能构成一个长度为k的组合
if d == 0: # 如果d为0,表示已经构成一个长度为k的组合
ans.append(path.copy()) # 将当前的组合路径复制并加入结果集
return # 结束当前递归
# 从当前位置i开始,向前搜索可以选取的元素,直到选取的元素个数不足以构成一个组合
for j in range(i, d-1, -1):
path.append(j) # 将当前元素加入组合路径
dfs(j-1) # 递归搜索下一个元素
path.pop() # 撤销当前选择,回溯到上一步
dfs(n) # 从n开始搜索组合
return ans # 返回所有组合结果
复杂度分析
时间复杂度:分析回溯问题的时间复杂度,有一个通用公式:路径长度×搜索树的叶子数。对于本题,它等于 O(k⋅C(n,k))。
空间复杂度:O(k)。返回值不计入。
选或不选
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
ans = [] # 用于存储所有可能的组合结果
path = [] # 用于存储当前的组合路径
def dfs(i: int) -> None: # 定义深度优先搜索(DFS)函数,参数i表示当前搜索的起始位置
d = k - len(path) # 计算当前还需要选取多少个元素才能构成一个长度为k的组合
if d == 0: # 如果d为0,表示已经构成一个长度为k的组合
ans.append(path.copy()) # 将当前的组合路径复制并加入结果集
return # 结束当前递归
if i > d: # 如果当前位置i大于还需选择的元素个数d,继续向前搜索
dfs(i - 1) # 递归搜索下一个位置
path.append(i) # 将当前元素加入组合路径
dfs(i - 1) # 递归搜索下一个位置
path.pop() # 撤销当前选择,回溯到上一步
dfs(n) # 从n开始搜索组合
return ans # 返回所有组合结果