题目描述:
给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。
例如,排列 [1,2,4] 是第 1 个排列。
class Solution {
public:
long long permutationIndex(vector<int> &A) {
vector<int> temp(A);//A复制给temp数组暂存
sort(A.begin(), A.end());
if(A == temp)
return 1;
long long count = 2;
while(next_permutation(A.begin(), A.end())){
//next_permutation()函数对该数组进行全排列的同时并改变A数组的值
if(temp == A){
break;
}else{
count ++;
}
}
return count;
}
};
运用STL标准库中的next_permutation()方法最方便,但是复杂度过高,不通过
第二种方法:
对于四位数,有4!种排列方式;
当知道第一位数,还有3!种方式;
当知道第二位数,还有2!种方式;
当知道第三位数,还有1!种方式;
前面三位都确定了,最后一位也确定了;
因此对前面n-1位,各位的权值为:
(n−1)! ( n − 1 ) ! , (n−2)! ( n − 2 ) ! , (n−3)! ( n − 3 ) ! , … , 1! 1 !
第一位之后的数小于第一位的个数为 x1 x 1 ;
第二位之后的数小于第二位的个数为 x2 x 2 ;
第三位之后的数小于第二位的个数为 x3 x 3 ;
……
第 (n−1) ( n − 1 ) 位之后的数小于第 (n−1) ( n − 1 ) 的个数为 xn−1 x n − 1 ;
因此index = x1 x 1 * (n−1)! ( n − 1 ) ! + x2 x 2 * (n−2)! ( n − 2 ) ! + … + xn−1 x n − 1 * 1! 1 ! + 1 1
class Solution {
public:
long long permutationIndex(vector<int> &A) {
vector<int> temp(A);
sort(A.begin(),A.end());
if(A == temp)
return 1;
long long sum = 0;
for(int i = 0; i < temp.size() - 1; i ++){
int index = 0;//统计比temp[i]要小且位于i位置之后的数字个数
for(int j = i + 1; j < temp.size(); j ++){
if(temp[j] < temp[i]){
index ++;
}
}
sum += index * fab(A.size() - i - 1);
}
return sum + 1;
}
long long fab(int x){//求阶乘
long long f;
if(x == 0 || x == 1)
f = 1;
else
f = fab(x - 1) * x;
return f;
}
};