题目描述:
给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从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
<script type="math/tex" id="MathJax-Element-230">1</script>
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;
}
};