【leetcode刷题笔记】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.


 

题解:

开始想用暴力来着,分别用了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了。

代码如下:

 1 class Solution {
 2 public:
 3     string getPermutation(int n, int k) {
 4         int f = 1;
 5         string answer = "";
 6 
 7         for(int i = 1;i<=n-1;i++){
 8             f *= i;
 9         }
10         //f = (n-1)!
11         k--;
12 
13         int nums[10] = {1,2,3,4,5,6,7,8,9};
14         for(int i = 0;i < n;i ++){
15             answer += nums[k/f] + '0';
16 
17             for(int j = k/f;j < n;j ++)
18                 nums[j] = nums[j+1];
19 
20             k = k%f;
21             if(n-i-1 > 0)
22                 f = f/(n-i-1);
23         }
24         return answer;
25     }
26 };

代码解释:

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

15行计算第i位上的数;

17行循环更新nums数组;

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

注意21行有个判断n-i-1是否大于0,因为最后一次循环,i=n-1,如果不判断,会出现除以0操作,程序会奔溃。

posted @ 2014-04-28 15:34  SunshineAtNoon  阅读(292)  评论(0编辑  收藏  举报