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