从给定字符串中查找长度为 k 的所有排列/组合

Posted

技术标签:

【中文标题】从给定字符串中查找长度为 k 的所有排列/组合【英文标题】:Find all permutations/combinations of length k from given string 【发布时间】:2018-10-14 23:49:43 【问题描述】:

这是在一次采访中问我的。给定一个字符串,我必须编写程序来查找长度为 k 的所有排列/组合。 所以对于 string = "cra" 和 length = 2 需要在向量中返回以下内容: "ca","cr","rc","ra","ac","ar"。不允许重复。

有什么建议吗?

我想出的是使用重复。基本上循环遍历所有字符并将其添加到序列中。当长度与给定长度匹配时,它将附加到最终向量。

【问题讨论】:

对它进行排序,然后在循环中为每个所需长度的子字符串调用std::next_permutation 您想要排列还是组合?有区别。 所有的排列都可以由这些字母组成。 【参考方案1】:

我会寻找递归的东西,因为我喜欢递归。 "cra" 中大小为 k 的子串是:

“c”,后跟“ra”中大小为 k-1 的子字符串 “r”,后跟大小为 k-1 的子串为“ca” “a”,后跟“cr”中大小为 k-1 的子字符串

所以如果我写 E 是 n 个字符的集合,并且 e_i 它的元素。

Substring(E, k) = "" if k = 0(是的,我也喜欢初始化 在 0 处重复) 和子串(E, k) = 并集(子串(e_i + 子串(E\e_i, k-1))) 如果 k>0

这种东西在黑板上比在数字文本中更合适。让我们尝试纯文本:

大小为 k 的集合 E 的子串是第一个字母为 e_i 的子串的 E 的每个元素在 e_i 上的并集。

我说清楚了吗?我不知道我是否清楚。

之后,如果您存储中间结果,则可以通过用计算时间换取内存使用来优化该方法,这样您就不必多次计算它们(对于 n = 3 无关紧要,但它当 n 变大时肯定很重要)。如果您的起始词是 abcdefgh 且 k = 5,您将存储诸如 substring("cdefgh", 3) 之类的内容,这样您就不必为以 a 开头的词和以 b 开头的词计算它。您将节省大量计算时间,但当 n 变大时可能需要大量内存。如果您有内存阈值,最好存储最小 k 的子字符串,因为那些将被请求最多的子字符串(递归树的结尾)。

最后一个问题:如何存放?我选择了使用对 ("cdefgh", 3) 或什至单独使用 "cdefgh" 作为键的映射,并将子字符串集作为值。

【讨论】:

【参考方案2】:

正如Slava 所提到的,你可以使用std::next_permutation,但我感觉面试官想看看你的技术能力,以了解烫发和复合是如何工作的。

Here 是一个有用的链接。它使用Java/C#,我看了一下,它看起来可以很容易地转换为C++。

该链接包含强烈的评论,非常适合了解解决方案的内部工作原理。

我希望这对您的下一次面试有用。 :)

【讨论】:

此链接使用重复。

以上是关于从给定字符串中查找长度为 k 的所有排列/组合的主要内容,如果未能解决你的问题,请参考以下文章

java字符串排列组合查找

从给定的数字中查找下一个最高的唯一数字

获取字符串全排列 或者 只输出k个的组合

当数组的数量和每个数组的长度未知时生成字符组合的所有排列

查找加起来为给定字符串的所有子字符串组合

获取字符串或组合的所有可能排列,包括 Java 中的重复字符