(day13)77. 组合

描述

给定两个整数 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  # 返回所有组合结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值