返回

LeetCode题解:77. 组合,JS回溯,DFS搜索,精辟注释

前端

前言

欢迎来到LeetCode题解系列,本系列文章将为你提供各种LeetCode题目的详细解答。在这一篇中,我们将重点介绍第77题:组合。组合问题是编程面试中常见的题目之一,它考察了候选人使用回溯算法和DFS搜索来解决复杂问题的编码能力。

问题

给你一个整数n,一个整数k,和一个长度为n的数组nums,要求你返回nums的所有可能的k个元素的组合。例如,对于nums = [1,2,3]和k = 2,返回[[1,2],[1,3],[2,3]]。

解法分析

该解法参考了46. 全排列的解法[LeetCode题解:46. 全排列,回溯,JavaScript,详细注释]。使用DFS生成所有可能的排列情况。我们需要使用used数组,标识每个值是否被使用过,同时used的index即为需要排列的数字。

由于subResult和used变量会在递归中不断变化,因此我们需要使用JavaScript的Array.slice()方法来复制这两个数组,以确保在每次递归调用中使用的是它们的副本,而不会影响原始数组的值。

代码实现

const combine = (nums, k) => {
  if (k <= 0 || nums.length < k) {
    return [];
  }

  const result = [];
  const subResult = [];
  const used = new Array(nums.length).fill(false);

  const backtrack = (start) => {
    if (subResult.length === k) {
      result.push([...subResult]);
      return;
    }

    for (let i = start; i < nums.length; i++) {
      if (used[i] === true) {
        continue;
      }

      subResult.push(nums[i]);
      used[i] = true;
      backtrack(i + 1);
      used[i] = false;
      subResult.pop();
    }
  };

  backtrack(0);
  return result;
};

复杂度分析

  • 时间复杂度:O(2^n),其中n是nums数组的长度。这是因为对于每个元素,我们都有两个选择:使用或不使用它。因此,总共有2^n种可能的组合。
  • 空间复杂度:O(n),这是用于存储subResult和used数组的空间。

结语

希望这篇文章能够帮助你理解LeetCode第77题:组合的解法。如果你还有任何疑问,请随时留言,我会尽快回复。