Leetcode 第K个排列

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

"123"
"132"
"213"
"231"
"312"
"321"
给定 n 和 k,返回第 k 个排列。

 

首先,我们先理解清楚全排列的过程。给定n=3,则123的全排列有{123,132,213,231,321,312};

具体先固定住1,对23进行全排序,然后交换1和2的位置,对13进行全排序,再交换1和3的位置,对21进行全排序。

但这道题目不可采取先递归求全排序所有可能,再取要的答案。因为第5个排列为 312而不是321。所以应考虑从其他角度入手。

当n=1时,有1种排列,
当n=2时,有2种排列,
当n=3时,有6种排列,
其实n=3时,可以拆分成第一位数和 后两位数,后两位数的排列组合为n=2时的两种,那第一位数可以是三个数种的任意一个,所以总的排列数就是23=6
所以我们可以知道,当k<=2时,第一位数没有变,那我们就可以确定第一个数是最小数,那就对剩下的后两位数分析,如果k=1那就确定第二位数是最小数,否则则是第二小数
当2<k<=4时,可以确定第一位数是第二小数,再对后两数分析,如果k=3那第位数就是剩下数里的最小数
所以以此举例n=4,k=9时,我们对k进行判断k如果是在123到1234之间的话,那说明k至少改变了4位,如果k在123到1232之间,说明第一位肯定是2,未确定是数位[1,3,4]
那k=k-6=3,那么k是在12 到123之间,说明k改变了3位,且k在12到12*2之间,那第二位就是3, 剩余未排列[1,4]
k = k-3 = 1,那么说明最后两位k未改变, 那么第三第四位就是1 4

代码如下:

class Solution {

public:

    string getPermutation(int n, int k) {

        string ans="";

        string base="";

        for(int i=1;i<=n;i++)

            base+=char('0'+i);

        if(k==1) return base;

        while(k>1)

        {

            adjust(base,n,k,ans);

        }

        ans+=base;

        return ans;

    }

 

    void adjust(string &s, int &n, int &k,string &ans)

    {

        int cur=jiecheng(n-1);

        int i=0;

        if(k<=cur )

        {

            n--;

            ans+=s[i];

            s.erase(i,1);

            cur=jiecheng(n-1);

        }

        while(k>cur)

            {

                i++;

                k-=cur;

            }  

         

        ans+=s[i];

        s.erase(i,1);

        n--;

    }

 

    int jiecheng( int n)

    {

        int val=1;

        for(int i=1;i<=n;i++)

            val*=i;

        return val;

    }

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值