打印所有可能的长度为k的字符串,这些字符串由n个字符组成,没有重复的结构

打印所有可能的由n个字符组成的长度为k的字符串是一个常见问题,并且已经有解决方法

但是,我希望知道

问题:有没有办法打印出所有可能的字符串而无需重复的结构?

重复结构示例[k = 3,n = {a,b,c}]:

  1. AAA = BBB = CCC

  2. ABB = ACC = BAA = BCC = CAA = CBB

  3. ABC = ACB = BAC = BCA = CAB = CBA

  4. ABA = ACA = BAB = BCB = CAC = CBC

  5. AAB = AAC = BBA = BBC = CCA = CCB

例如:

输入: k=3n={a,b,c}

输出:

aaa
aab
aba
abb
abc

对于复杂度要求:不应大于O(n^k)


蝴蝶刀刀
浏览 203回答 1
1回答

翻翻过去那场雪

您可以调整现有解决方案。您需要添加的限制是,一个字符只能在列表中的所有其他字符至少出现一次之后才能出现在字符串中。之所以起作用,是因为对于具有相同重复结构的每组字符串,每个字符的首次出现均以它们在列表中出现的顺序出现,因此这是您输出的字符串。您可以使用额外的参数来强制执行此限制:static void printAllKLengthRec(char[] set,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String prefix,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int n, int k, int validCount){&nbsp; &nbsp; // Base case: k is 0, print prefix&nbsp; &nbsp; if (k == 0)&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(prefix);&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; // One by one add all valid characters and recursively call for k equals to k-1&nbsp; &nbsp; for (int i = 0; i < validCount; ++i)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // Next character of input added&nbsp; &nbsp; &nbsp; &nbsp; String newPrefix = prefix + set[i];&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // increment the valid count if all characters up till then have already&nbsp; &nbsp; &nbsp; &nbsp; // appeared and there are characters that have not yet appeared&nbsp; &nbsp; &nbsp; &nbsp; // (i.e. validCount < n)&nbsp; &nbsp; &nbsp; &nbsp; int newValidCount = (i == (validCount - 1)) && (validCount < n) ?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validCount + 1 :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validCount;&nbsp; &nbsp; &nbsp; &nbsp; // k is decreased, because we have added a new character&nbsp; &nbsp; &nbsp; &nbsp; printAllKLengthRec(set, newPrefix,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n, k - 1, newValidCount);&nbsp;&nbsp; &nbsp; }}因此,例如,如果您的集合为{'a', 'b', 'c', 'd'}且validCount为3,则意味着a和b已经出现,因此可以将a或b或c附加到字符串中。如果追加c,则在递归调用函数之前增加值,因为现在a和b和c至少出现过一次,因此可以追加d。如果添加a或b,则该值将保持不变。对于排列中的第一个字符,只能显示列表中的第一个字符:static void printAllKLength(char[] set, int k){&nbsp; &nbsp; int n = set.length;&nbsp;&nbsp; &nbsp; printAllKLengthRec(set, "", n, k, 1);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java