Permutation Sequence
Question
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 for n = 3:
"123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence.
Note:
Given n will be between 1 and 9 inclusive. Given k will be between 1 and n! inclusive.
Example 1:
Input: n = 3, k = 3 Output: "213"
Example 2:
Input: n = 4, k = 9 Output: "2314"
Approach 1: 缩小问题规模
要想解决本题,首先需要了解一个简单的结论:
对于 n 个不同的元素(例如数 1, 2,
, n),它们可以组成的排列总数目为 n!。
对于给定的 n 和 k,我们不妨从左往右确定第 k 个排列中的每一个位置上的元素到底是什么。
我们首先确定排列中的首个元素
以 1 为
的排列一共有 个; 以 2 为
的排列一共有 个; 以 n 为
的排列一共有 个。
由于我们需要求出从小到大的第 k 个排列,因此:
- 如果
,我们就可以确定排列的首个元素为 1; - 如果
,我们就可以确定排列的首个元素为 2; - 如果
,我们就可以确定排列的首个元素为 n。 因此,第 k 个排列的首个元素就是:
当我们确定了
- 以
最小的元素为 的排列一共有 个; - 以
次小的元素为 的排列一共有 个; - 以
最大的元素为 的排列一共有 个;
其中
求
算法
设第 k 个排列为
我们从小到大枚举 i:
我们已经使用过了 i-1 个元素,剩余 n-i+1 个元素未使用过,每一个元素作为 a_i 都对应着 (n-i)!个排列,总计 (n-i+1)! 个排列;
因此在第 k 个排列中,
即为剩余未使用过的元素中第 小的元素; 在确定了
后,这 个元素的第 k 个排列,就等于 之后跟着剩余 n-i 个元素的第 个排列。
在实际的代码中,我们可以首先将 k 的值减少 1,这样可以减少运算,降低代码出错的概率。对应上述的后两步,即为:
因此在第 k 个排列中,
即为剩余未使用过的元素中第 小的元素; 在确定了
后,这 n-i+1 个元素的第 k 个排列,就等于 之后跟着剩余 n-i个元素的第 个排列。
实际上,这相当于我们将所有的排列从 0 开始进行编号。
1 | class Solution: |
复杂度分析
时间复杂度:
。 空间复杂度:
。
思考题
对于给定的排列
解答:
反思
我在分析这个问题的时候只考虑到了第一项怎么确定,然后就用递归来求解问题,中间忽略了n和k的取值特例。分析不够完备,代码看着比较乱,可读性不强。今后分析的时候还是要把问题分析完整了再编代码,比如推出这道题的通项公式后再写代码。