Lintcode 197 Permutation Index

题意

给定不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号,编号从1开始。比如[1,2,3]是字典序中的第一个,那么return 1

链接

https://www.lintcode.com/problem/197/?showListFe=true&page=1&pageSize=50&problemTypeId=1

思路

假设我要找[3,1,2,4]排第几个
首先对于第一位来说,我要找到比3小的数,1和2,这些数字开头的序列字典序肯定比[3,1,2,4]小,以这些数字为开头的有2*3!个, 接下来第一位就固定为3了,看第二位,第二位没有比1小的,那排在以3,1开头前面的有0*2!个数以此类推有
n为数组的长度, a n a_n an为在第n位之后,比第n位小的数字个数
得到康托展开
f ( n ) = a 0 ∗ ( n − 1 ) ! + a 1 ∗ ( n − 2 ) ! . . . + a n 0 ! f(n) = a_0*(n-1)! + a_1*(n-2)! ... + a_n0! f(n)=a0(n1)!+a1(n2)!...+an0!

解法

有树状数组的解法,能快速求解 a n a_n an, WIP(logn)

class Solution {
public:
    /**
     * @param a: An array of integers
     * @return: A long integer
     */
    long long permutationIndex(vector<int> &a) {
        // write your code here
        int n = a.size();
        int pow = 1;
        long long add = 1;
        long long res = 0;
        for(int i = n-1; i >= 0; i--) {
            res = res + findPath(i,a) * add;
            add = add * pow;
            pow = pow + 1;
        }
        res += 1;
        return res;
    }

    int findPath(int u, vector<int>& a) {
        int cnt = 0;
        for(int i = u+1; i < a.size(); i++) {
            if(a[i] < a[u]) {
                cnt++;
            }
        }
        return cnt;
    }
};

算法复杂度 O ( n 2 ) O(n^2) O(n2)
空间复杂度 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值