http://www.lintcode.com/en/problem/permutation-index-ii/
import java.util.HashMap;
import java.util.Map;
public class Solution {
/*
* @param A: An array of integers
* @return: A long integer
*/
public long permutationIndexII(int[] A) {
// write your code here
// 分析:对于数组1,4,2,2. 每一位拥有一个系数k,对于第i位, k = (len - i) !.
// 例如第二位数字4的系数为(4 - 2)!=2!。此处代表的含义为:
// 假如我们固定前二位的数字(此时指针在第二位,则代表第一位固定仍为1。仅2,3,4 位数字可以自由组合)
// ,那么可以出现的组合种类为2!×M 种。M代表第二位后,
// 比第二位的数字小的数字出现的次数,此处为2,2,共两次。
// 此处需要计算M,因为第二位不可以和第三四位一起全排列。因为为了保证在1,4,2,2 的字典序之前,
// 第二位也就是指针当前位必须小于4.此时还需要除去重复元素的出现次数2!。
// 所以指针在第二位时,排列种类为2!×2 / 2!个。然后移动指针到下一位。
Map counter = new HashMap<>();
long res = 1;
// 计算阶乘
long factor = 1;
// 计算重复次数
long repeate = 1;
for (int i = A.length - 1; i >= 0; i--) {
int count = 1;
if (counter.containsKey(A[i])) {
count += counter.get(A[i]);
}
counter.put(A[i], count);
// 计算重复次数
repeate *= count;
int small = 0;
// 计算比自己小的数
for (int j = i + 1; j < A.length; j++) {
if (A[j] < A[i]) {
small++;
}
}
res += small * factor / repeate;
factor *= A.length - i;
}
return res;
}
}