【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操作,程序会奔溃。

你可能感兴趣的:(LeetCode)