zoukankan      html  css  js  c++  java
  • [LeetCode]76. Permutation Sequence全排列序列

    The set [1,2,3,…,n] contains a total of n! unique permutations.

    By listing and labeling all of the permutations in order,
    We get the following sequence (ie, for n = 3):

    1. "123"
    2. "132"
    3. "213"
    4. "231"
    5. "312"
    6. "321"

    Given n and k, return the kth permutation sequence.

    Note: Given n will be between 1 and 9 inclusive.

    Subscribe to see which companies asked this question

     
    解法:这道题是让求出n个数字的第k个排列组合,由于其特殊性,我们不用将所有的排列组合的情况都求出来,然后返回其第k个,我们可以只求出第k个排列组合即可,那么难点就在于如何知道数字的排列顺序,可参见网友喜刷刷的博客,首先我们要知道当n = 3时,其排列组合共有3! = 6种,当n = 4时,其排列组合共有4! = 24种,我们就以n = 4, k = 17的情况来分析,所有排列组合情况如下:

    1234
    1243
    1324
    1342
    1423
    1432
    2134
    2143
    2314 
    2341
    2413
    2431
    3124
    3142
    3214
    3241
    3412 <--- k = 17
    3421
    4123
    4132
    4213
    4231
    4312
    4321

    我们可以发现,每一位上1,2,3,4分别都出现了6次,当第一位上的数字确定了,后面三位上每个数字都出现了2次,当第二位也确定了,后面的数字都只出现了1次,当第三位确定了,那么第四位上的数字也只能出现一次,那么下面我们来看k = 17这种情况的每位数字如何确定,由于k = 17是转化为数组下标为16:

    候选数字序列"123456789"

    最高位可取1,2,3,4中的一个,每个数字出现3!= 6次,所以k = 16的第一位数字的下标为16 / 6 = 2,即3被取出
    第二位此时从1,2,4中取一个,k = 16是此时的k' = 16 % (3!) = 4(由于确定了第一位是3,因此第一位为1和2的所有全排列都可以去除了,所以k=k-2*(3!)=4,也即是k%(3!)),而剩下的每个数字出现2!= 2次,所以第二数字的下标为4 / 2 = 2(此时3已经从候选数字中删除了),即4被取出
    第三位此时从1,2中去一个,k' = 4是此时的k'' = 4 % (2!) = 0,而剩下的每个数字出现1!= 1次,所以第三个数字的下标为 0 / 1 = 0,即1被取出
    第四位是从2中取一个,k'' = 0是此时的k''' = 0 % (1!) = 0,而剩下的每个数字出现0!= 1次,所以第四个数字的下标为0 / 1= 0,即2被取出

    那么我们就可以找出规律了
    a1 = k / (n - 1)!
    k1 = k

    a2 = k1 / (n - 2)!
    k2 = k1 % (n - 2)!
    ...

    an-1 = kn-2 / 1!
    kn-1 = kn-2 / 1!

    an = kn-1 / 0!
    kn = kn-1 % 0!

    class Solution {
    public:
        string getPermutation(int n, int k) {
            string res = "";
            vector<int> fac(n, 1);
            for (int i = 2; i < n; ++i)
                fac[i] = i * fac[i - 1];
            string num = "123456789";
            --k;
            for (int i = 0; i < n; ++i) {
                int idx = k / fac[n - 1 - i];
                res += num[idx];
                num.erase(idx, 1);
                k %= fac[n - 1 - i];
            }
            return res;
        }
    };

     参考:http://www.cnblogs.com/grandyang/p/4358678.html

  • 相关阅读:
    TF用法指导
    二叉搜索树
    霍夫曼树
    集成学习—boosting和bagging
    值得关注的博客或者文章
    ElasticSearch中的sort排序和filedData作用
    ElasticSearch--validate验证搜索语句是否合法或者存在语法错误
    elasticsearch中query和filter的区别
    深度认识 Sharding-JDBC:做最轻量级的数据库中间层
    elasticserach数据库深度分页查询的原理
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4961412.html
Copyright © 2011-2022 走看看