您的位置:首页 > 产品设计 > UI/UE

【leetcode刷题笔记】Permutation Sequence

2014-04-28 15:34 253 查看
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):

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.

题解:

开始想用暴力来着,分别用了STL中的next_permutation函数和自己写的字典序实现的next_permutation函数,结果都TLE在n=9这里了,最后上网找了资料才发现这题是有规律的。

以n=3为例,我们用一个数组nums放1,2,3,所以nums = [1,2,3],假设k=4

那么如果先不考虑第一位,后n-1位总共的排列有(n-1)!个,所以第一位数就可以算出来在nums中的index就是(k-1)/(n-1)!,本例中就是(4-1)/2!=1,所以第一位数是nums[1]=2。这里k为什么要减1呢?因为如果k不减1,那么k分别取1,2,3,4,5,6时,我们得到的第一位数分别在nums中的位置是0,1,1,2,2,3,发现正好“错位”,实际应该是0,0,1,1,2,2,把k-1就正好可以得到正确的解。

然后看第二位,注意在算第二位数字前要先更新k和nums,更新k’=(k-1)/(n-1)!=3/2 =1;更新nums,把2后面的每一个数往前移动一位,覆盖前面的数,本例得到的新的nums=[1,3],表示剩下的几位数在1,3中取。那么第二位数在nums中的index就可以算出来是k’/(n-2)!=1/1=1,即nums[1]=3。

最后一位数就是nums中剩下的1了。

代码如下:

class Solution {
public:
string getPermutation(int n, int k) {
int f = 1;
string answer = "";

for(int i = 1;i<=n-1;i++){
f *= i;
}
//f = (n-1)!
k--;

int nums[10] = {1,2,3,4,5,6,7,8,9};
for(int i = 0;i < n;i ++){
answer += nums[k/f] + '0';

for(int j = k/f;j < n;j ++)
nums[j] = nums[j+1];

k = k%f;
if(n-i-1 > 0)
f = f/(n-i-1);
}
return answer;
}
};


代码解释:

第7行循环计算(n-1)!;

15行计算第i位上的数;

17行循环更新nums数组;

20~23行更新k和f,f存放各阶的阶乘,在循环的过程中从(n-1)!一直到1;

注意21行有个判断n-i-1是否大于0,因为最后一次循环,i=n-1,如果不判断,会出现除以0操作,程序会奔溃。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: