Permutation Sequence

解法一:最容易想到的就是求出所有的排列组合结果,然后找到第K个返回。

class Solution {
public:
    bool flag[15];
    char s[15];
    string ans;
    int count = 0;
    void cal(int n, int index, int k)
    {
        if(count == k) return;
        if(index >= n)
        {
            count ++ ;
            if(count == k) ans = s;
            return;
        }
        for(int i = 1; i <= n; i ++)
        {
            if(flag[i] == false)
            {
                s[index] = i + '0';
                flag[i] = true;
                cal(n, index + 1, k);
                flag[i] = false;
            }
        }
    }
    string getPermutation(int n, int k) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        memset(flag, 0, sizeof(flag));
        memset(s, '\0', sizeof(s));
        ans = "";
        count = 0;
        cal(n, 0, k);
        return ans;
    }
};

解法二:利用规律,逐个计算出结果中每一位应该是什么数字。假设结果是ans, 明显ans是一个n位的string,我们现在要做的就是把ans的每一位放入正确的字符。

对于ans的第index位,题目给定的求第K个,这时index后面还有 x = n - index - 1位,令 k_small = k / x!(取上整),第index位就应该是 n位数字中没有被选择过的第k_small小的数字, 同时k也需要更新 k -= (k_small - 1) * x! .

class Solution {
public:
    bool flag[15];
    char s[15];
    int f[15];
    
    int find_k_small(int n, int k_small)
    {
        int count = 0;
        for(int i = 1; i <= n; i ++)
        {
            if(flag[i] == false)
    		{
				count ++ ;
				if(count == k_small) 
				{
					flag[i] = true;
					return i;
				}
			}
        }
        return 0;
    }
    
    void cal(int n, int k)
    {
        int index = 0;
        int k_small;
        while(index < n)
        {
            int len = n - index - 1;
            k_small = k / f[len];
            if(k % f[len] != 0) 
            {
                k_small ++ ;
            }
            s[index] = find_k_small(n, k_small) + '0';
            index ++ ;
            k -= (k_small - 1) * f[len];
        }
    }
    string getPermutation(int n, int k) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        memset(flag, 0, sizeof(flag));
        memset(s, '\0', sizeof(s));
        f[0] = f[1] = 1;
        for(int i = 2; i < 10; i ++)
            f[i] = i * f[i-1];
        cal(n, k);
        return string(s);
    }
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值