康托展开其实就是将一个全排列映射成一个数,即将这个排列的信息保存为一个数
公式:X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!
注意:a[i]指的是:此排列中,这个数后面有多少个数比它小,i指的是它当前所处的位置。
所有的全排列都可以映射为唯一的(各不相同的)一个整数。实际上这个整数的含义是指它前面的数列有多少个。
例如A={3,5,7,8,9}的一个排列为B={7,9,5,3,8}
则B的X值为:
1. 7后面有2个数(3和5)比它小, 2*((5-1)!)=48;
2. 9后面有3个数(5,3,8)比它小,3*((5-2)!)=18;
3. 5后面有1个数(3)比它小, 1*((5-3)!)=2;
4. 3后面有0个数比它小, 0*((5-4)!)=0;
5. 8的后面有0个数比它小, 0*(0!)=0;
算出 X=68;
A的任意排列的X值最大为n!-1
既然A的任意排列都对应一个(个不同的)X,那么必然可以由X逆推出这个排列。
一般题目要求n个数的第k大的排列,则X的值为k-1。
例如{1,2,3,4,5,6}求第10大的,X=9;
1. 9%((6-1)!)=0+9 选最小的数 1 并去掉1,得{2,3,4,5,6},新集{1}
2. 9%((6-2)!)=0+9 选最小的数 2 并去掉2,得{3,4,5,6},新集{1,2}
3. 9%((6-3)!)=1+3 选第二小的数 4 并去掉4 ,得{3,5,6},新集{1,2,4}
4. 3%((6-4)!)=1+1 选第二小的数 5 去掉 得{3,6},新集{1,2,4,5}
5. 1%((6-5)!)=1+0 选第二小的数 6 去掉 得{3},新集{1,2,4,5,6}
6. 0%(0!)=0+0 选最小的数3 去掉 得{} ,新集{1,2,4,5,6,3}
原集为{}结束
排列为{1,2,4,5,6,3}
以上就是逆康托展开