题目描述:给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例: 输入: n = 4, k = 2 输出: [
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
在深度优先搜索中,有时我们会去掉一些不符合题目要求的、没作用的答案,进而得到正确答案。这个丢掉答案的过程,形似减掉树的枝叶,所以这一方法被称为“剪枝”。
在这道题中,要做到剪枝,我们需要分别在组合问题的递归式和递归边界上动手脚:
- 递归式:普通组合问题,每到一个新的坑位处,我们都需要对组合结果数组进行更新;这道题中,当且仅当组合内数字个数为
k个时,才会对组合结果数组进行更新。 - 递归边界:只要组合内数字个数达到了
k个,就不再继续当前的路径往下遍历,而是直接返回。
/*** @param {number} n* @param {number} k* @return {number[][]}*/const combine = function(n, k) {// 初始化结果数组const res = []// 初始化组合数组const subset = []// 进入 dfs,起始数字是1dfs(1)// 定义 dfs 函数,入参是当前遍历到的数字function dfs(index) {if(subset.length === k) {res.push(subset.slice())return}// 从当前数字的值开始,遍历 index-n 之间的所有数字for(let i=index;i<=n;i++) {// 这是当前数字存在于组合中的情况subset.push(i)// 基于当前数字存在于组合中的情况,进一步 dfsdfs(i+1)// 这是当前数字不存在与组合中的情况subset.pop()}}// 返回结果数组return res};
