leetcode197——排列序号

题目描述:
给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从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位,各位的权值为:
(n1)! ( n − 1 ) ! , (n2)! ( n − 2 ) ! , (n3)! ( n − 3 ) ! , … , 1! 1 !
第一位之后的数小于第一位的个数为 x1 x 1 ;
第二位之后的数小于第二位的个数为 x2 x 2
第三位之后的数小于第二位的个数为 x3 x 3
……
(n1) ( n − 1 ) 位之后的数小于第 (n1) ( n − 1 ) 的个数为 xn1 x n − 1 ;
因此index = x1 x 1 * (n1)! ( n − 1 ) ! + x2 x 2 * (n2)! ( n − 2 ) ! + … + xn1 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;
    }
};

你可能感兴趣的:(C++,数据结构)