sl1673495 / leetcode-javascript

:beers: 喝杯小酒,一起做题。前端攻城狮从零入门算法的宝藏题库,根据知名算法老师的经验总结了 100+ 道 LeetCode 力扣的经典题型 JavaScript 题解和思路。已按题目类型分 label,一起加油。
2.09k stars 344 forks source link

组合-77 #70

Open sl1673495 opened 4 years ago

sl1673495 commented 4 years ago

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combinations 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

定义一个 helper 函数,递归的时候接受本次处理的 start 起始位置,和上一次已经取了字符后得到的 prev 数组。继续进一步的循环递归,增加 start 和拼接 prev 即可。

prev 的长度等于 k 时,条件满足,把当前的 prev 存入结果数组中。

image

/**
 * @param {number} n
 * @param {number} k
 * @return {number[][]}
 */
let combine = function (n, k) {
  let ret = []

  let helper = (start, prev) => {
    let len = prev.length
    if (len === k) {
      ret.push(prev)
      return
    }

    if (start > n) {
      return
    }

    for (let i = start; i <= n; i++) {
      helper(i + 1, prev.concat(i))
    }
  }
  helper(1, [])
  return ret
}

剪枝

在循环中,要考虑当前已经凑成的数组长度和剩下的数字所能凑成的最大长度,对于不可能凑成的情况直接 continue

let combine = function (n, k) {
  let ret = []

  let helper = (start, prev) => {
    let len = prev.length
    if (len === k) {
      ret.push(prev)
      return
    }

    if (start > n) {
      return
    }

    // 还有 rest 个位置待填补
    let rest = k - prev.length
    for (let i = start; i <= n; i++) {
      if (n - i + 1 < rest) {
        continue
      }
      helper(i + 1, prev.concat(i))
    }
  }
  helper(1, [])
  return ret
}
jinfang12345 commented 4 years ago

function test(n, k, start=1) { const result = []; for (let index = start; index <= n; index++) { if (k > 1) { const a = test(n, k - 1, index + 1); if (a && a.length) { a.forEach(item => { result.push([index].concat(item)); }); } } else if (k === 1) { result.push([index]); } } return result; }

daomingQian commented 3 years ago
var combine = function(n, k) {
    let res = [];

    function tfs(start, path){
        let length = path.length;
        if(length === k){
            res.push([...path]);
            return;
        }
        if(length > k) return;
        let rest = k-length;
        for(let i=start; i<=n; i++) {
            if(rest > n-start+1) break;
            path.push(i)
            tfs(i+1,path)
            path.pop();
        }
    }

    tfs(1,[])

    return res;
};