题目描述:给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

    示例: 输入: n = 4, k = 2 输出: [

    [2,4],

    [3,4],

    [2,3],

    [1,2],

    [1,3],

    [1,4],

    ]

    在深度优先搜索中,有时我们会去掉一些不符合题目要求的、没作用的答案,进而得到正确答案。这个丢掉答案的过程,形似减掉树的枝叶,所以这一方法被称为“剪枝”。

    在这道题中,要做到剪枝,我们需要分别在组合问题的递归式和递归边界上动手脚:

    • 递归式:普通组合问题,每到一个新的坑位处,我们都需要对组合结果数组进行更新;这道题中,当且仅当组合内数字个数为 k 个时,才会对组合结果数组进行更新。
    • 递归边界:只要组合内数字个数达到了 k 个,就不再继续当前的路径往下遍历,而是直接返回。
    1. /**
    2. * @param {number} n
    3. * @param {number} k
    4. * @return {number[][]}
    5. */
    6. const combine = function(n, k) {
    7. // 初始化结果数组
    8. const res = []
    9. // 初始化组合数组
    10. const subset = []
    11. // 进入 dfs,起始数字是1
    12. dfs(1)
    13. // 定义 dfs 函数,入参是当前遍历到的数字
    14. function dfs(index) {
    15. if(subset.length === k) {
    16. res.push(subset.slice())
    17. return
    18. }
    19. // 从当前数字的值开始,遍历 index-n 之间的所有数字
    20. for(let i=index;i<=n;i++) {
    21. // 这是当前数字存在于组合中的情况
    22. subset.push(i)
    23. // 基于当前数字存在于组合中的情况,进一步 dfs
    24. dfs(i+1)
    25. // 这是当前数字不存在与组合中的情况
    26. subset.pop()
    27. }
    28. }
    29. // 返回结果数组
    30. return res
    31. };