Tony's Log

Algorithms, Distributed System, Machine Learning

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Simply a variation to "Permutation Index". When calculating current digit index, we consider duplicated case.

Again, similar as "Digit Counts", it is another counting problem and stil digit by digit.

And please note: we can use Fenwick Tree to calculate rank by O(nlgn)

class Solution 
{
    long long dupPerm(unordered_map<int, int> &hash) 
    {
        if (hash.empty()) return 1;

        long long dup = 1;
        for (auto it = hash.begin(); it != hash.end(); ++it) 
        {
        dup *= w(it->second);
        }

        return dup;
    }
    long long w(int n) // n*(n-1)*..*2*1
    {
        long long ret = 1;
        while(n > 1)
        {
            ret *= n;
            n --;
        }
        return ret;
    }
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) 
    {
        int n = A.size();
        if(!n) return 0;
        
        long long index = 1;
        long long factor= w(n - 1);
        
        //  MSB -> LSB
        for(int i = 0; i < n; i ++)    
        {
            // Calc rank
          int rank = 0;
          for(int j = i + 1; j < n; j ++)
          {            
            if(A[i] > A[j])
              rank ++;
          }
          
          // Calc dup factor
            unordered_map<int, int> hm;          
            for(int j = i; j < n; j ++)
                ++hm[A[j]];
      
            index += rank * factor / dupPerm(hm);
            if(i < (n - 1))factor /= n - i - 1;
        }
        
        return index;
    }
};
posted on 2015-11-04 08:56  Tonix  阅读(299)  评论(0编辑  收藏  举报