题目
给出集合 [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"
思路
1.固定第一位,比较k和(n-1)!的大小,确定第一位的值
2.递归
实现
class Solution {
public:
string getPermutation(int n, int k) {
string res;
vector<int> tmp;
for (int i = 1; i <= n; ++i) {
tmp.push_back(i);
}
func1(n, k, &tmp, &res);
return res;
}
void func1(int n, int k, vector<int>* tmp, string*res) {
int m = k / func(n - 1);
int avail = k - m * func(n - 1);
cout << m << "\t" << k << "\t" << avail << endl;
if (avail == 0) {
*res += std::to_string((*tmp)[m - 1]);
tmp->erase(tmp->begin() + m - 1);
cout << "size: " << tmp->size() << endl;
for (int i = tmp->size() - 1; i >= 0; --i) {
*res += std::to_string((*tmp)[i]);
}
return;
}
*res += std::to_string((*tmp)[m]);
tmp->erase(tmp->begin() + m);
func1(n - 1, avail, tmp, res);
}
int func(int n) {
int res = 1;
while (n > 1) {
res = res * n;
--n;
}
return res;
}
};
class Solution {
public:
string getPermutation(int n, int k) {
string res;
set<int> tmp = {};
func1(n, n, k, &tmp, &res);
return res;
}
void func1(int max, int n, int k, set<int>* tmp, string*res) {
int m = k / func(n - 1);
int avail = k - m * func(n - 1);
if (avail == 0) {
int count = 0;
for (int i = 1; i <= max; ++i) {
if (tmp->find(i) == tmp->end()) {
++count;
}
if (count == m) {
*res += std::to_string(i);
tmp->emplace(i);
break;
}
}
for (int i = max; i >= 1; --i) {
if (tmp->find(i) == tmp->end()) {
*res += std::to_string(i);
tmp->emplace(i);
}
}
return;
}
int count = 0;
for (int i = 1; i <= max; ++i) {
if (tmp->find(i) == tmp->end()) {
++count;
}
if (count == m + 1) {
*res += std::to_string(i);
tmp->emplace(i);
func1(max, n - 1, avail, tmp, res);
break;
}
}
}
int func(int n) {
int res = 1;
while (n > 1) {
res = res * n;
--n;
}
return res;
}
};