[LeetCode] Permutation Sequence 序列排序

 

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

By listing and labeling all of the permutations in order, we get the following sequence for n = 3:数组

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

Given n and k, return the kth permutation sequence.post

Note:url

  • Given n will be between 1 and 9 inclusive.
  • Given k will be between 1 and n! inclusive.

Example 1:spa

Input: n = 3, k = 3
Output: "213"

Example 2:code

Input: n = 4, k = 9
Output: "2314"

 

这道题是让求出n个数字的第k个排列组合,因为其特殊性,咱们不用将全部的排列组合的状况都求出来,而后返回其第k个,咱们能够只求出第k个排列组合便可,那么难点就在于如何知道数字的排列顺序,可参见网友喜刷刷的博客,首先咱们要知道当n = 3时,其排列组合共有3! = 6种,当n = 4时,其排列组合共有4! = 24种,咱们就以n = 4, k = 17的状况来分析,全部排列组合状况以下:htm

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
4321blog

咱们能够发现,每一位上1,2,3,4分别都出现了6次,当最高位上的数字肯定了,第二高位每一个数字都出现了2次,当第二高位也肯定了,第三高位上的数字都只出现了1次,当第三高位肯定了,那么第四高位上的数字也只能出现一次,下面咱们来看k = 17这种状况的每位数字如何肯定,因为k = 17是转化为数组下标为16:排序

最高位可取1,2,3,4中的一个,每一个数字出现3!= 6次(由于当最高位肯定了,后面三位能够任意排列,因此是3!,那么最高位的数字就会重复3!次),因此k = 16的第一位数字的下标为16 / 6 = 2,在 "1234" 中即3被取出。这里咱们的k是要求的坐标为k的全排列序列,咱们定义 k' 为当最高位肯定后,要求的全排序列在新范围中的位置,同理,k'' 为当第二高为肯定后,所要求的全排列序列在新范围中的位置,以此类推,下面来具体看看:ip

第二位此时从1,2,4中取一个,k = 16,则此时的 k' = 16 % (3!) = 4,注意思考这里为什么要取余,若是对这24个数以6个一组来分,那么k=16这个位置就是在第三组(k/6 = 2)中的第五个(k%6 = 4)数字。以下所示,而剩下的每一个数字出现2!= 2次,因此第二数字的下标为4 / 2 = 2,在 "124" 中即4被取出。

3124
3142
3214
3241
3412 <--- k' = 4
3421

第三位此时从1,2中去一个,k' = 4,则此时的k'' = 4 % (2!) = 0,以下所示,而剩下的每一个数字出现1!= 1次,因此第三个数字的下标为 0 / 1 = 0,在 "12" 中即1被取出。

3412 <--- k'' = 0
3421

第四位是从2中取一个,k'' = 0,则此时的k''' = 0 % (1!) = 0,以下所示,而剩下的每一个数字出现0!= 1次,因此第四个数字的下标为0 / 1= 0,在 "2" 中即2被取出。

3412 <--- k''' = 0

那么咱们就能够找出规律了
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;
        string num = "123456789";
        vector<int> f(n, 1);
        for (int i = 1; i < n; ++i) f[i] = f[i - 1] * i;
        --k;
        for (int i = n; i >= 1; --i) {
            int j = k / f[i - 1];
            k %= f[i - 1];
            res.push_back(num[j]);
            num.erase(j, 1);
        }
        return res;
    }
};

 

相似题目:

Next Permutation

Permutations

 

参考资料:

https://leetcode.com/problems/permutation-sequence/description/

https://leetcode.com/problems/permutation-sequence/discuss/22508/An-iterative-solution-for-reference

 

LeetCode All in One 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索