查找n个字母表的所有排列的算法

时间:2010-08-07 22:24:55

标签: java algorithm permutation

我编写了以下算法来查找n个唯一字母表的所有可能排列。

Set<String> results = new HashSet<String>();
    int size = 1;
            //find the total permutations possible
    for(int i=0;i<array.length;i++){
        size*=(i+1);            
    }
    // i is the number of items remaining to be shuffled.
    while(results.size()<size){
        for (int i = array.length; i > 1; i--) {
            // Pick a random element to swap with the i-th element.
            int j = rng.nextInt(i);  // 0 <= j <= i-1 (0-based array)
            // Swap array elements.
            char tmp = array[j];
            array[j] = array[i-1];
            array[i-1] = tmp;
        }
        StringBuffer str = new StringBuffer();          
        for(int i=0;i<array.length;i++)
            str.append(array[i]);
        results.add(str.toString());
    }
    System.out.println(results);

1)有什么方法可以改进这个算法吗? 2)该算法的时间复杂度是多少?

PS:我向那些对我previous post做出反应的人道歉。在寻求帮助之前,我会亲自尝试。

4 个答案:

答案 0 :(得分:3)

通过使用随机改组,你将有一个大量的次迭代次数,最终没有将新项目放入集合中 - 你应该寻找一种方法来确保每次迭代时,一个新项目被放入集合中(通过'new',我只是指一个以前没有见过的排列)。

我不想猜测上面提供的算法的复杂性 - 它会很大。

答案 1 :(得分:3)

  

1)有什么方法可以改进这个算法吗?

是。只是为了给你一些提示,你如何确定性地产生排列:

  • 想象N元素上所有排列的词典顺序。想象一下,在前面的

  • 中,你怎么能按照那个顺序生成下一个排列
  • 考虑具有共同前缀的排列集(例如 435 126, 435 162等)是什么样的,你怎么能用它在算法中。

答案 2 :(得分:2)

生成排列的最佳方法是迭代地这样做:找到一个从一个排列到下一个排列的方案,直到你看到它们为止。 Knuth已经在TAOCP的一个组合分册中暴露了这样的方案,并且没有进入类似汇编的伪代码,你可能想要检查these nifty C implementation of those algorithms。您正在寻找的算法是生成排列的算法。

这种算法与我(我所理解的)相反的优势在于它是确定性的,并且每次都会产生不同的排列。

答案 3 :(得分:0)

感谢您的投入。我想我有一个更好的算法。请提供意见

private static List<String> allPerms(char[] array) {    
  List<String> perms = new ArrayList<String>();
  if(array.length<=1 )
      perms.add(String.valueOf(array[0]));
  else{
      char[] newarray = Arrays.copyOf(array, array.length-1);
      char lastChar = array[array.length-1];
      List<String> soFar = allPerms(newarray);
      for(int i=0; i<soFar.size(); i++) {       
          String curr = soFar.get(i);
          for(int j=0;j<array.length;j++){
              StringBuffer buff = new StringBuffer(curr);
              perms.add(buff.insert(j, lastChar).toString());                 
          }
      }       
    }
return perms; }