标签:lse 顺序 输入 元素 else math 接下来 情况 void
给出集合 [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 = 3
输出: "213"
示例 2:
输入: n = 4, k = 9
输出: "2314"
思路
利用位掩码来记录数字的选择状态
class Solution {
public:
string ans;
int vis[10];
void dfs(string& cur, int mask, int n, int& k) {
if (cur.size() == n) {
k--;
if (!k) ans=cur;
return;
}
for (int j=1; j<=n; j++) if ((mask & (1 << j-1)) == 0) {
cur += to_string(j);
dfs(cur, mask | (1<<j-1), n, k);
cur.pop_back();
if (!k) return;
}
}
string getPermutation(int n, int k) {
string cur="";
memset(vis, 0, sizeof vis);
dfs(cur, 0, n, k);
return ans;
}
};
复杂度分析
比如 n=4,k=9 时:
注:假设从 n+1 层回退到上一层 n 的时候,由于第 n 层的选择是无效的,所以 vis 数组对 n+1 层选择的数字不会做出撤销
class Solution {
public:
string s;
int n,st[10],fac[10];
void dfs(int& k) {
if(s.size()==n){
return;
}
int c=fac[n-s.size()-1];
for (int j=1; j<=n; j++) if (!st[j]) {
if (k>c) {
k-=c;
} else {
st[j]=1, s+=to_string(j);
dfs(k);
}
}
}
string getPermutation(int n, int k) {
fac[0]=1;
for (int i=1; i<=n; i++) fac[i]=fac[i-1]*i;
this->n=n;
dfs(k);
return s;
}
};
复杂度分析
标签:lse 顺序 输入 元素 else math 接下来 情况 void
原文地址:https://www.cnblogs.com/zerostart0/p/13619439.html