Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. You may return the answer in any order.
Example 1:
Input: n = 4, k = 2Output:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]
Example 2:
Input: n = 1, k = 1Output: [[1]]
Constraints:
n: 1, 2, 3, 4 k: 2
组合问题中, 不同顺序的解为同一个。比如 [1, 2], [2, 1]
为相同解。
此外可以发现规律, 保留所有增序排列的解
即为组合的解。
/*** @param {number} n* @param {number} k* @return {number[][]}*/var combine = function(n, k) {const result = []backTrace(n, k, 1, [], result)return result};var backTrace = function(n, k, index, temp, result) {if (temp.length === k) {if (ifIncrease(temp)) {result.push([...temp])}return}for (let i = index; i <= n; i++) {temp.push(i)backTrace(n, k, index + 1, temp, result)temp.pop()}}var ifIncrease = function(arr) {for (let i = 0; i < arr.length - 1; i++) {if (arr[i] >= arr[i + 1]) return false}return true}
提交, 此时报超时的错误。经排查发现, 截支的地方存在问题, 当前在 temp 中的值被重复使用了。修改如下
- backTrace(n, k, index + 1, temp, result)+ backTrace(n, k, i + 1, temp, result)
/*** @param {number} n* @param {number} k* @return {number[][]}*/var combine = function(n, k) {const result = []backTrace(n, k, 1, [], result)return result};var backTrace = function(n, k, index, temp, result) {if (temp.length === k) {result.push([...temp])return}for (let i = index; i <= n; i++) {temp.push(i)backTrace(n, k, i + 1, temp, result)temp.pop()}}
还是以 n = 5, k = 3
为例, 上述代码中, 实际遍历的顺序如下:
* 1* 2* 3* 4* 5* 3* 4* 5* 4* 5* 5 // 减支* 2* 3* 4* 5* 4* 5* 5 // 减支* 3* 4* 5* 5 // 减支* 4 // 减支
此时, 当第一列的值到达 3 时, 达到搜索上界
, [3, 4, 5] 是其中一个解。如果再往后遍历, 4 作为解的开头, 则位数达不到 3 位, 不满足要求了。同理第二列的搜索上界为 4。第三列的搜索上界为 5。接着结合代码进行优化:
/*** @param {number} n* @param {number} k* @return {number[][]}*/var combine = function(n, k) {const result = []backTrace(n, k, 1, [], result)return result};var backTrace = function(n, k, index, temp, result) {if (temp.length === k) {result.push([...temp])return}// 题目可以转化为从搜索上界到 n 中要取的数字长度为 (k - temp.length)。// 可以得出搜索上界为: n - (k - temp.length) + 1for (let i = index; i <= n - (k - temp.length) + 1; i++) {temp.push(i)backTrace(n, k, i + 1, temp, result)temp.pop()}}