Problem 24

问题描述:

A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012   021   102   120   201   210

What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

 

解决方法:

 

以012的组合为例子,所有的交换都基于012最小的数字。

   2! 1!

0:0  1  2

1:0  2  1    1= 1!  

2:1  0  2    2 = 2! 

3:1  2  0     3=2!+1!

4:2  0  1     4=2*2!  

5:2  1  0     5 = 2*2! + 1!  先将0和2交换,此时数字为210,然后将1和0交换,此时数字为201,完成了2*2!种变换,然后将1和0交换,完成了1!种变化,则此时的数字210就是我们经过2*2!+1!变换的数字。

 

 

An  An-1  ....A1

当An确定时,其余n-1位有(n-1)!种排列,那么第n位确定后,就有An*(n-1)!种排列。

而第n-1則有An-1 * (n-2)!

當前n-1位確定,那麼最後一定也就是肯定的!

 

 10000000 = 2*9!+6*8!+6*7!+2*6!+5*5!+1*4!+2*3!+1*2!+1!

开始是0123456789

第一步将2和0交换。得到2103456789,然后交换1和0,得到2013456789。最高位确定为2.

第二步将7和0交换。得到2713456089,然后交换0之前,7之后的数字,得到2701345689。

。。。

其实每次第一次交换后,就是将剩下的数字再次由小到大排序。

为什么呢?

以0123为例子,

第23个是3201,既是 22 =  3×3! + 2×2!

先将3和0交换,得到3120,此时并不是滴3*3!个,得到第3*3!需要将其余的几位排序。

这里大家好好想想。

 

 

	public static final Long UP = 9876543210L;
	public static final int START = 123;
	public static final int Last = 1000000;
	public static final int HIGH = 9;
	public static int[] Number = new int[9];
	public static final int[] Element = {0,1,2,3,4,5,6,7,8,9};
	
	public static long Factorial(int number){
		long r = 1;
		
		for(int i=number; i>1; i--){
			r *= i;
		}
		
		return r;
	}
	
	public static void ai_find(){
		
		Arrays.fill(Number, 0);
		int remain = Last-1;
		int high = HIGH;
		int posititon = 0;
		while(remain!=0){
			long value = Factorial(high);
			long num = 0;
			if(remain>=value){
				num = remain/value;
				remain -= value*num;
				Number[posititon] = (int)num;
			}else{
				Number[posititon] = 0;
			}
			System.out.println("Position:"+posititon+",value:"+value+",num:"+num+",remain:"+remain);
			posititon++;
			high--;
			
		}
		
		for(int i=0; i<Number.length; i++){
			System.out.print(Number[i]+",");
		}
		
		boolean[] matcher = new boolean[10];
		Arrays.fill(matcher, false);
		
		String str = "";
		for(int i=0;i<Number.length; i++){
			int index = 0;
			for(int j=0; j<matcher.length; j++){
				if(index==Number[i]&&!matcher[j]){
					str = str + j;
					matcher[j] = true;
					break;
				}
				if(!matcher[j]){
					index++;
				}
			}
		}
		for(int i=0; i<matcher.length; i++){
			if(!matcher[i]){
				str = str + i;
			}
		}
		System.out.println(str);
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值