21 字典序排列

排列指的是将一组物体进行有顺序的放置。例如,3124是数字1、2、3、4的一个排列。
如果把所有排列按照数字大小或字母先后进行排序,我们称之为字典序排列。0、1、2的字典序排列是:
012 021 102 120 201 210
求数字0、1、2、3、4、5、6、7、8、9的字典序排列中第一百万位的排列是什么?
output :2783915460

算法分析:
这里用到阶乘的概念,比如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、
https://blog.csdn.net/visame/article/details/2455396

这是另一位胖友用JAVA写的字典序列算法:
https://blog.csdn.net/qq_28394425/article/details/53083589
我觉得他的方法和本文写的很相似。

附上两个字典序列算法的算法思路讲解:
(1)讲解了算法思路和举例子
https://blog.csdn.net/chengzhibin416/article/details/97009047

当排第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)字典排序算法详解 + 代码实现
https://blog.csdn.net/qq_34672688/article/details/79557380

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值