列出具有重复字母的字符串的唯一排列的算法

时间:2016-11-22 21:52:10

标签: algorithm permutation

例如,string" AAABBB"将有排列: " ABAABB&#34 ;, " BBAABA&#34 ;, " ABABAB&#34 ;, 等

什么是生成排列的好算法? (以及它的时间复杂性是什么?)

3 个答案:

答案 0 :(得分:2)

对于multiset,您可以按位置(JavaScript代码)递归求解:



function f(multiset,counters,result){
  if (counters.every(x => x === 0)){
    console.log(result);
    return;
  }

  for (var i=0; i<counters.length; i++){
    if (counters[i] > 0){
      _counters = counters.slice();
      _counters[i]--;
      f(multiset,_counters,result + multiset[i]);
    }
  }
}

f(['A','B'],[3,3],'');
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这不是完整的答案,只是一个想法。

如果你的字符串只有两个字母的固定数字,我将使用二叉树和良好的递归函数。 每个节点都是包含父名称前缀和后缀A或B的名称的对象,此外,它在名称中包含A和B字母的数字。

节点构造函数从父节点获取父节点的名称和A和B的编号,因此它只需要将1添加到A或B的编号,并将一个字母添加到name。

如果分别有超过三个A(在A节点的情况下)或B,或者它们的总和等于起始字符串的长度,则不构造下一个节点。

现在你可以收集2棵树的叶子(它们的名字)并拥有你需要的所有排列。

Scala或某些功能语言(具有类似对象的功能)非常适合实现此算法。希望这有助于或只是激发一些想法。

答案 2 :(得分:0)

由于您实际上想要生成排列而不是仅计算它们,因此您可以期望的最佳复杂度是O(size_of_output)。

这是一个很好的Java解决方案,可以很快地运行,但占用的空间可以忽略不计。它首先对字母进行排序以找到词典上最小的排列,然后以词法顺序生成所有排列。

它被称为Pandita算法:https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order

import java.util.Arrays;
import java.util.function.Consumer;


public class UniquePermutations
{
    static void generateUniquePermutations(String s, Consumer<String> consumer)
    {
        char[] array = s.toCharArray();
        Arrays.sort(array);
        for (;;)
        {
            consumer.accept(String.valueOf(array));

            int changePos=array.length-2;
            while (changePos>=0 && array[changePos]>=array[changePos+1])
                --changePos;

            if (changePos<0)
                break; //all done

            int swapPos=changePos+1;
            while(swapPos+1 < array.length && array[swapPos+1]>array[changePos])
                ++swapPos;

            char t = array[changePos];
            array[changePos] = array[swapPos];
            array[swapPos] = t;

            for (int i=changePos+1, j = array.length-1; i < j; ++i,--j)
            {
                t = array[i];
                array[i] = array[j];
                array[j] = t;
            }
        }
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        StringBuilder line = new StringBuilder();
        generateUniquePermutations("banana", s->{
            if (line.length() > 0)
            {
                if (line.length() + s.length() >= 75)
                {
                    System.out.println(line.toString());
                    line.setLength(0);
                }
                else
                    line.append(" ");
            }
            line.append(s);
        });
        System.out.println(line);
    }
}

这是输出:

aaabnn aaanbn aaannb aabann aabnan aabnna aanabn aananb aanban aanbna
aannab aannba abaann abanan abanna abnaan abnana abnnaa anaabn anaanb
anaban anabna ananab ananba anbaan anbana anbnaa annaab annaba annbaa
baaann baanan baanna banaan banana bannaa bnaaan bnaana bnanaa bnnaaa
naaabn naaanb naaban naabna naanab naanba nabaan nabana nabnaa nanaab
nanaba nanbaa nbaaan nbaana nbanaa nbnaaa nnaaab nnaaba nnabaa nnbaaa