📜  制作所有大小为k的组合(1)

📅  最后修改于: 2023-12-03 15:36:57.559000             🧑  作者: Mango

制作所有大小为k的组合

在程序开发中,经常会碰到制作所有大小为k的组合的场景,例如给定一个数组,找出其中所有长度为k的子集。本文将介绍两种常见的方法:回溯法和递归法。

回溯法

回溯法是一种基于深度优先搜索的算法,常用于在一组可能的解中搜索出一个满足要求的解。在制作大小为k的组合时,我们通过不断递归枚举数组中的元素,并保存当前已选组合。当组合大小达到k时,将当前组合加入结果数组。随后回溯到上一级,继续枚举下一个元素,直到所有情况均被考虑。

下面是一个基于回溯法的JavaScript代码片段:

function backtrack(result, temp, nums, k, start) {
  if (temp.length === k) {
    result.push([...temp]);
    return;
  }
  for (let i = start; i < nums.length; i++) {
    temp.push(nums[i]);
    backtrack(result, temp, nums, k, i + 1);
    temp.pop();
  }
}

function combinations(nums, k) {
  const result = [];
  backtrack(result, [], nums, k, 0);
  return result;
}

上述代码中,backtrack函数为递归实现,result保存所有符合要求的组合,temp保存当前已选的数字,nums为原始数组,k为目标组合长度,start表示搜索起点。combinations为入口函数,调用backtrack得到结果数组。

递归法

递归法是一种更为简洁的方法,相较于回溯法,不需要显式地维护当前已选组合。我们将原始数组划分为两个部分:第一个元素和其余元素。对于以第一个元素为开头的所有大小为k-1的组合,再加上第一个元素,即可得到所有大小为k的组合。随后递归处理除第一个元素外的所有元素。

下面是一个基于递归法的Python代码片段:

def combinations(nums, k):
  if k == 0:
    return [[]]
  if len(nums) < k:
    return []
  ans = []
  for item in combinations(nums[1:], k-1):
    ans.append([nums[0]]+item)
  ans += combinations(nums[1:], k)
  return ans

上述代码中,nums为原始数组,k为目标组合长度。特别地,当k为0时,返回一个空数组。当nums长度小于k时,返回一个空数组。ans保存所有符合条件的组合,通过递归实现。