/** * @param {number} n * @param {number} k * @return {number[][]} * https://leetcode.cn/problems/combinations/ */ const combine = function (n, k) { }; /* 利用回溯可以轻松的解决这个问题,定义结果esult=[]用来收集结果,定义backtrack(path, start)来收集结果和回溯 path:用来收集路径 start: 用来标记选择组合元素的起始位置,因为组合对顺序没有要求{1,2},{2,1}算一个组合,避免重复 */ function f1(n, k) { const result = []; // 收集符合要求的组合 const backtrack = (path, start) => { // 如果path的长度符合要求,收集结果,当path.length === k 时 if (path.length === k) { result.push([...path]); return; // 结束这个路径的收集 } // 从start开始选择元素放入path,进行组合 for (let i = start; i <= n; i++) { // 将当前元素加入组合 path.push(i); // 递归,组合新的元素 backtrack(path, i + 1); // 回溯,将之前的组合路径去掉 path.pop(); } }; backtrack([], 1); return result; } /* 剪枝优化 */ function f2(n, k) { const result = []; // 收集符合要求的组合 const backtrack = (path, start) => { if (path.length + (n - start + 1) < k) return; // 剪枝优化 // 如果path的长度符合要求,收集结果,当path.length === k 时 if (path.length === k) { result.push([...path]); return; // 结束这个路径的收集 } // 从start开始选择元素放入path,进行组合 for (let i = start; i <= n; i++) { // 将当前元素加入组合 path.push(i); // 递归,组合新的元素 backtrack(path, i + 1); // 回溯,将之前的组合路径去掉 path.pop(); } }; backtrack([], 1); return result; }