问题描述:
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); }