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;
    }
  • 相关阅读:
    动态代理有啥用(总结)
    ES6随笔--各数据类型的扩展(4)--数组和对象
    ES6随笔--各数据类型的扩展(2)--数值
    ES6随笔--各数据类型的扩展(1) --字符串和正则
    ES6随笔--声明变量
    CommonJS随记
    DOM练习小记--一个简单的Web页面游戏
    js随笔--关于事件
    js随笔--关于this
    js随笔--循环里的弯弯绕
  • 原文地址:https://www.cnblogs.com/qingcheng/p/3785992.html
Copyright © 2011-2022 走看看