我编写了以下算法来查找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做出反应的人道歉。在寻求帮助之前,我会亲自尝试。答案 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; }