zoukankan      html  css  js  c++  java
  • LeetCode OJ--Permutation Sequence *

    求第k个排列。

    刚开始按照一个排列一个排列的求,超时。

    于是演算了一下,发下有数学规律,其实就是康托解码。

    康托展开:全排列到一个自然数的双射

    X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!

    ai为整数,并且0<=ai<i(1<=i<=n)

     适用范围:没有重复元素的全排列

    全排列的解码

    如何找出第16个(按字典序的){1,2,3,4,5}的全排列?

    1. 首先用16-1得到15

    2. 用15去除4! 得到0余15

    3. 用15去除3! 得到2余3

    4. 用3去除2! 得到1余1

    5. 用1去除1! 得到1余0

    有0个数比它小的数是1,所以第一位是1

    有2个数比它小的数是3,但1已经在之前出现过了所以是4

    有1个数比它小的数是2,但1已经在之前出现过了所以是3

    有1个数比它小的数是2,但1,3,4都出现过了所以是5

    最后一个数只能是2

    所以排列为1 4 3 5 2

    class Solution{
    public:
        string getPermutation(int n, int k)
        {
            //get fractial
            vector<int> fractial;
            fractial.push_back(1);
            for(int i = 1;i<n;i++)
            {
                fractial.push_back(fractial[i-1]*(i+1));
            }
            //to mark if this digit selected ,true means can be selected, false means already selected.
            vector<bool> allnum;
            for(int i = 0; i <=n; i++)
                allnum.push_back(true);
    
            int ChuShu = k - 1, YuShu = 0;
            string ans;
            int weishu = 0;
    
            while(weishu<n)
            {
                int _num_i;
                int place;
                if(weishu == n-1) // the last digit
                    _num_i = select(allnum,1);
                else
                {
                    YuShu = ChuShu % fractial[n-2-weishu];
                    place = ChuShu / fractial[n-2-weishu];
                     
                    _num_i = select(allnum,place + 1 );
                }
                ChuShu = YuShu;
                weishu ++;
                char ch = '3' - 3 + _num_i;
                ans += ch;
            }
            return ans;
        }
        int select(vector<bool> &allnum,int place)
        {
            int i = 1;
            
            while(place)
            {
                if(allnum[i] == true)
                {
                    place--;
                    if(place == 0)
                        break;
                }
                i++;
            }
            allnum[i] = false;
            return i;
        }
    };
    
    int main()
    {
        class Solution myS;
        cout<<myS.getPermutation(5,16);
        return 0;
    }
  • 相关阅读:
    搭建ARL资产安全灯塔
    免杀技术发展史
    米酷CMS 7.0.4代码审计
    腾讯安全实习 应用运维安全面试
    Docker部署CTF综合性靶场,定时刷新环境
    西湖论剑2020MISC-Yusa_yyds
    (转)马云炮轰银行监管的解读
    ATT&CK 实战
    Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用
    修改CH340芯片信息
  • 原文地址:https://www.cnblogs.com/qingcheng/p/3785992.html
Copyright © 2011-2022 走看看