算法分析:
这里用到阶乘的概念,比如n可以组合成n*(n-1)*(n-2)**21中方式。只需要计算(n-1)的阶乘即可,就可以知道除了n有多少种形式,然后把i放到数的最前面,i是list中第几个元素,list的初始元素相当于已经排序好的,然后在通过不断的递归即可求出。
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<10; i++) {
list.add(i);
}
//0是第一个,999999是第一百万个
System.out.println(Lexicographic(10, 999999, list));
}
public static String Lexicographic(int num, int max, ArrayList<Integer> list) {
if(num > 0) {
int prexLexicographicNum = 1;
if(num != 1) {
prexLexicographicNum = recursion(num-1);
}
int quotients = max / prexLexicographicNum;
int mod = max % prexLexicographicNum;
int i = list.remove(quotients);
return i + "" + Lexicographic(num-1, mod, list);
}
return "";
}
public static int recursion(int num) {
if(num ==1)
return 1;
return num * recursion(num - 1);
}
我并不是很了解如何求出序列的全排列,看了大神的博客文章,也还是不太明白emmmmmm、
这是另一位胖友用JAVA写的字典序列算法:
我觉得他的方法和本文写的很相似。
附上两个字典序列算法的算法思路讲解:
(1)讲解了算法思路和举例子
当排第i位时,后面还10-i位可以排,有全排列(10-i)!种情况,再乘比这个数小的个数 就是之前排过的个数 举个栗子: 1 2 3 4的情况
3412:
排第一位3时,后面还有(4-1)个空,共3!=6种情况,比3小的数有1 2 其中未使用的数有1 2两个,那么在排第一位前有2×3!=12个数
排第二位4时,后面还有(4-2)个空,共2!=2种情况,比4小的数有1 2 3 其中未使用的有1 2两个,那么在排第二位前有2×3!+2×2!=16个数
排第三位1时,后面还有(4-3)个空,共1!=1种情况,比1小且未使用的数有0个,那么在排第三位前有2×3!+2×2!+0×1!=16个数
排第四位2时,后面还有(4-4)个空,共0!=1种情况,比2小的数有1,其中未使用的数有0个,那么在排第四位前有2×3!+2×2!+0×1!+0×0!=16个数
所以3412是第17个数。
、
推广一下,第n个数前面有n-1个数,那么每位abcdefghij满足的条件就是a×(10-1)!+b×(10-2)!+……+j(10-10)!=n-1,以此为思路,只需要从大到小来遍历每个数即可,由于唯一性且存在阶乘的关系,不可能存在重复的数,因此不需要额外条件
(2)字典排序算法详解 + 代码实现
因篇幅问题不能全部显示,请点此查看更多更全内容