Given a permutation which may contain repeated numbers, find its index in all the permutations of these numbers, which are ordered in lexicographical order. The index begins at 1.
Example
思路是对于每一个字符,找到所有比他小的字符的集合, 然后对于集合中的每个字符,先把他去掉,查看剩下下有多少种作何方式(用排列组合去重)然后再把那个字符添回来;
Given the permutation [1, 4, 2, 2]
, return 3
.
每个字符完成后,删掉后进行下一个字符的运算:
c++
class Solution {
public:
/**
* @param A an integer array
* @return a long integer
*/
long long permutationIndexII(vector<int>& A) {
// Write your code here
// Write your code here
vector<int> B = A;
const int len = A.size();
vector<long long> dp = {0};
long long res = 1;
for (long long i = 1; i< len; i++) {
if (i == 1)
dp.push_back(1);
else
dp.push_back(dp[i - 1] * i);
}
sort(B.begin(), B.end());
for (int i = 0; i < A.size(); i++) {
auto itr = lower_bound(B.begin(), B.end(), A[i]);
int ind = itr - B.begin();
int fake_head = INT_MIN;
for (int j = 0; j < ind; j++) {
if (B[j] != fake_head) {
int k = B[j];
B.erase(B.begin() + j);
res+=get_permutation_num(B, dp);
B.insert(B.begin() + j, k);
fake_head = B[j];
}
}
//cout<<res<<endl;
B.erase(itr);
}
return res;
}
long long get_permutation_num(vector<int>& vec, vector<long long>& dp) {
sort(vec.begin(), vec.end());
vector<int> dup_num;
long long res = 1;
int acl_num = 1;
int dup = vec[0];
for (int i = 1; i < vec.size(); i++) {
if (vec[i] != dup) {
dup_num.push_back(acl_num);
dup = vec[i];
acl_num = 1;
} else {
acl_num++;
}
res*=((long long)i + 1);
}
dup_num.push_back(acl_num);
for (int i = 0; i < dup_num.size(); i++) {
res/=dp[dup_num[i]];
}
return res;
}
};