LintCode_198 Permutation Index II



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;
    }
};




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章