当前位置: 首页 > 面试题库 >

从n返回k个元素的所有组合的算法

晋坚
2023-03-14
问题内容

我想编写一个函数,该函数以字母数组作为参数,并选择多个字母。

假设您提供8个字母的数组,并希望从中选择3个字母。然后您将获得:

8! / ((8 - 3)! * 3!) = 56

返回由3个字母组成的数组(或单词)。


问题答案:

格雷码您会遇到的一个问题当然是记忆力,而且很快,您的集合中会有20个元素出现问题-20 C 3 =1140。而且,如果要遍历集合,最好使用修改后的灰色代码算法,因此您不必将所有代码都保存在内存中。这些将根据之前的内容生成下一个组合,并避免重复。其中有许多用于不同用途。我们是否要最大化连续组合之间的差异?最小化?等等。

蔡斯的小提琴(算法

Phillip J Chase,“ 算法382:N个对象中M个的组合 ”(1970年)

在C算法 …

词典顺序的组合索引(Buckles算法515)

您也可以按组合索引(按字典顺序)引用组合。意识到索引应该是基于索引从右到左的一些变化,我们可以构造一些应该恢复组合的东西。

因此,我们有一组{1,2,3,4,5,6} …并且我们想要三个元素。假设{1,2,3},我们可以说元素之间的差是1,顺序是最小。{1,2,4}有一个变化,按字典顺序是数字2。因此,最后一位的“变化”数量说明了字典顺序中的一个变化。具有更改{1,3,4}的第二个位置具有一个更改,但由于它位于第二个位置(与原始集中元素的数量成正比),因此说明了更多更改。

我描述的方法似乎是一种解构,从设置到索引,我们需要做相反的事情–这要复杂得多。这就是扣具解决问题的方式。我写了一些C来计算它们,并做了些微改动–我使用集合的索引而不是数字范围来表示集合,因此我们始终从0 … n开始。注意:

  1. 由于组合是无序的,因此{1,3,2} = {1,2,3}-我们将它们排序为词典顺序。
  2. 此方法具有隐式0,以开始第一个差异的集合。

词典顺序组合索引(McCaffrey)

还有另一种方法:它的概念更易于掌握和编程,但是没有优化Buckles。幸运的是,它也不会产生重复的组合:

例如:27 = C(6,4) + C(5,3)+C(2,2)+C(1,1)。因此,第四件事情的第27种字典组合是:{1,2,5,6},这些是您要查看的任何集合的索引。下面的示例(OCaml)需要choose函数,留给读者:

(* this will find the [x] combination of a [set] list when taking [k] elements *)
let combination_maccaffery set k x =
    (* maximize function -- maximize a that is aCb              *)
    (* return largest c where c < i and choose(c,i) <= z        *)
    let rec maximize a b x =
        if (choose a b ) <= x then a else maximize (a-1) b x
    in
    let rec iterate n x i = match i with
        | 0 -> []
        | i ->
            let max = maximize n i x in
            max :: iterate n (x - (choose max i)) (i-1)
    in
    if x < 0 then failwith "errors" else
    let idxs =  iterate (List.length set) x k in
    List.map (List.nth set) (List.sort (-) idxs)

一个简单的组合迭代器

出于教学目的,提供了以下两种算法。它们实现了迭代器和(更通用的)文件夹的整体组合。它们尽可能快,具有复杂度O(n C k)。内存消耗受约束k。

我们将从迭代器开始,该迭代器将为每个组合调用用户提供的函数

let iter_combs n k f =
  let rec iter v s j =
    if j = k then f v
    else for i = s to n - 1 do iter (i::v) (i+1) (j+1) done in
  iter [] 0 0

从初始状态开始,更通用的版本将调用用户提供的函数以及状态变量。由于我们需要在不同状态之间传递状态,因此我们不会使用for循环,而是使用递归,

let fold_combs n k f x = let rec loop i s c x = if i < n then loop (i+1) s c @@ let c = i::c and s = s + 1 and i = i + 1 in if s < k then loop i s c x else f c x else x in loop 0 0 [] x



 类似资料:
  • 我对C很在行,我正在尝试做一些黑客挑战,以此作为解决这个问题的方法 现在我正在努力解决愤怒的孩子们的问题:https://www.hackerrank.com/challenges/angry-children 基本上,它要求创建一个程序,给定一组N个整数,为该集合的K长度子集找到最小可能的“不公平”。不公平定义为K长度子集的最大值和最小值之间的差值。 我现在要做的是找到所有的K长度子集,计算它们

  • 给定一组未排序的整数,返回大小为k的所有子集(即每组有k个唯一元素),其总和为0。 所以我给了面试官以下解决方案(我在GeekViewpoint上研究过)。没有使用额外的空间,一切都做到位,等等。但当然成本是O(n^k)的高时间复杂度,其中在解决方案中。 但随后她提出了以下要求: 必须在答案中使用hashmap以降低时间复杂度 必须绝对地为一般情况提供时间复杂度 k=6时的提示,O(n^3) 她对

  • 问题描述 这道题是 LeetCode 77 题。 给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。 解法一:回溯法 递归 k 层。每层选取一个数,然后递归地选取 k-1 个数,直到选够 k 个数为止。设每层的数字区间为 [start, end],则这一层可以选择 [start, end-(k-1)] 的任何一个数 i,只要给下一层留出 k-1 个数即可。下一层的数字区间为

  • 这是一个算法问题。如果我错过了Python中任何有帮助的现有函数,请大喊一声。 给定一组元素的,我们可以在Python中使用函数来找到所有唯一的k元素子集。让我们调用包含所有这些子集的集合。请注意,每个这样的子集都有不同的元素。 问题是两步走。首先,给定这些k-不同元素子集,我想组合(其中的一些),这样(组合只是一些子集的超集): > 构图中任意两个子集之间的交集为空 构图中所有子集的并集给出的正

  • 我有一个运行的整数流,如何在任何时间点从这个流中获取最大的k个元素。

  • 我想从数组创建所有可能的数组可能大于或小于。输出数组中的元素不必是唯一的。 例如: 根据这个数组 给定所需大小的函数,应返回: 例2 根据这个数组 给定所需大小的函数,应返回: 用Swift怎么做?