给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。
样例
样例 1:
输入:[1,2,4]
输出:1
样例 2:
输入:[3,2,1]
输出:6
解题思路:
需要知道一个算法:康托展开。
原理介绍
**X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0! **
A[i] 指的是位于位置i后面的数小于A[i]值的个数,后面乘的就是后面还有多少个数的阶乘
说明 :这个算出来的数康拖展开值,是在所有排列次序 - 1的值,因此X+1即为在全排列中的次序
列 :
在(1,2,3,4,5)5个数的排列组合中,计算 34152的康托展开值。
带入上面的公式
X = 2 * 4! + 2 * 3! + 0 * 2! + 1 * 1! + 0 * 0!
=>X = 61
依次为思路进行写代码:
public class Solution {
/**
* @param A: An array of integers
* @return: A long integer
*/
public long permutationIndex(int[] A) {
// write your code here
long res = 1; //结果
long len = A.length; //标记当前元素后面还剩多少元素
for(int i=0; i<A.length; i++){
long times = 0; //记录当前元素后面有多少是小于当前元素的
len--;
for(int j=i+1; j<A.length; j++)
if(A[j] < A[i])
times++;
//计算len的阶乘
long temp = 1;
for(long j=len; j>0; j--)
temp *= j;
res += times*temp;
}
return res;
}
}