首页 > 其他 > 详细

【LeetCode 60】第k个排列

时间:2019-11-20 20:57:24      阅读:98      评论:0      收藏:0      [点我收藏+]

题目链接

【题解】


逆康托展开。
考虑康托展开的过程。
K = ∑v[i]*(n-i)!
其中v[i]表示在a[i+1..n]中比a[i]小的数字的个数
(也即未出现的数字中它排名第几(从0开始))
那么我们在逆康托展开的时候,就可以通过直接除(n-i)!得到每个数字的v[i]的值。
然后通过给已经出现的数字打tag。
剩下的问题就转化为找未出现的第v[i]个数字了。
注意康托展开的值是比当前序列小的序列的个数。
所以如果要找序号为k的序列的话,实际上应该找k-1对应的逆康托序列

【代码】

class Solution {
public:

    string getPermutation(int n, int k) {
        int fac[10],tag[10];
        memset(tag,0,sizeof(tag));
        int a[10];
        fac[0] = 1;
        for (int i = 1;i <= 9;i++) fac[i] = fac[i-1]*i;
        k--;
        for (int i = 1;i <= n;i++){
            for (int j = 1,l=k/fac[n-i];j<=n;j++){
                if (tag[j]==0){
                    l--;
                    if (l<0){
                        a[i] = j;
                        tag[j] = 1;
                        break;
                    }
                }
            }
            k=k%fac[n-i];
        }
        string s ="";
        for (int i = 1;i <= n;i++){
            s = s+(char)(a[i]+'0');
        }
        return s;
    }
};

【LeetCode 60】第k个排列

原文:https://www.cnblogs.com/AWCXV/p/11899757.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!