搜索
您的当前位置:首页正文

21 字典序排列

来源:易榕旅网

算法分析:
这里用到阶乘的概念,比如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)字典排序算法详解 + 代码实现

因篇幅问题不能全部显示,请点此查看更多更全内容

Top