题目
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例1
输入:
n = 3, k = 2
输出:
“213”
示例2
输入:
n = 4, k = 9
输出:
“2314”
解法
当n=4,k=9时
- 以1开头的组合有(4-1)!=6种
- 以2开头的组合有(4-1)!=6种
- 以3开头的组合有(4-1)!=6种
- 由此可见第1个字符对应(9-1)/6+1=2 第2大的数是2
- 2从4个字符中排除,剩下3个字符(1,3,4),9%6 = 3
- 以1开头的组合有(3-1)!=2种
- 以3开头的组合有(3-1)!=2种
- 以4开头的组合有(3-1)!=2种
- 由此可见第2个字符对应(3-1)/2+1=2 第2大的数是3
- 3从3个字符中排除,剩下2个字符(1,4),3%2 = 1
- 以1开头的组合有(2-1)!=1种
- 以4开头的组合有(3-1)!=1种
- 由此可见第3个字符为(1-1)/2+1=1 第1大的数是1
- 以此类推
代码
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
string getPermutation(int n, int k) {
vector<int> f(n,0);
vector<int> vis(n+1,1);
string ans;
f[0] = 1;
for(int i=1;i<n;i++){
f[i] = f[i-1]*i;
}
k--;
for(int i=0;i<n;i++){
int num = k/f[n-i-1]+1;
int id = 0;
for(int i=1;i<=n;i++){
if(vis[i] == 1)
id++;
if(id==num){
ans += to_string(i);
vis[i] = 0;
break;
}
}
k %= f[n-i-1];
}
return ans;
}
};
int main(){
int n=4,k=9;
Solution s;
cout<<s.getPermutation(n, k);
return 0;
}
今天也是爱zz的一天哦!