【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 @   SunshineAtNoon  阅读(297)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示