60. 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):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
1.首先让k是从0开始的数,k--
2.根据规律可以看出当 n = 3 第一个字符,为‘1’,k区间应该是(0, 2!],‘2’对应区间(2!, 2*2!] ...
3.根据2中规律得到第一个字符,如果得到的是‘1’,那么就要k不变,若得到‘2’,k -= 2! (减去1开头的那些字符串) ...
4.用新的k值和区间继续算后面的字符,其中还要维持一个vector,装可用的字符(按顺序),算出的字符将其从vector中拿出,后面的字符只从vector中选
代码:
class Solution {
public:
string getPermutation(int n, int k) {
int limit;
vector<char> valid;
string result = "";
for (int i = 0; i < n; i++) {
char a = '0' + i + 1;
valid.push_back(a);
}
k--;
while (n) {
limit = 1;
for (int i = 2; i < n; i++) limit *= i;
int i;
for (i = 0; i < n; i++) if (k >= limit*i && k < limit*(i+1)) break;
char a = valid[i];
std::vector<char>::iterator it = valid.begin();
k -= limit*i;
while (i--) it++;
valid.erase(it);
result += a;
n--;
}
return result;
}
};
回溯代码(超时):
class Solution {
public:
string find(string now, int n, int k, bool *status, int &count) {
if (now.length() == n) {
count++;
if (count == k) return now;
else return "";
}
for (int i = 0; i < n; i++) {
if (status[i]) {
status[i] = false;
char a = '0'+i+1;
string result = find(now+a, n, k, status, count);
if (result != "") return result;
status[i] = true;
}
}
return "";
}
string getPermutation(int n, int k) {
bool *status = new bool[n];
for (int i = 0; i < n; i++)
status[i] = true;
int count = 0;
return find("", n, k, status, count);
}
};
回溯法(解决超时):
class Solution {
public:
string find(string now, int n, int &k, bool *status) {
if (now.length() == n) {
k--;
if (k == 0) return now;
else return "";
}
for (int i = 0; i < n; i++) {
if (status[i]) {
status[i] = false;
char a = '0'+i+1;
string result = find(now+a, n, k, status);
if (result != "") return result;
status[i] = true;
}
}
return "";
}
string getPermutation(int n, int k) {
bool *status = new bool[n];
for (int i = 0; i < n; i++)
status[i] = true;
int limit = 1;
for (int i = 2; i < n; i++) limit *= i;
int i = 0;
for (i = 0; i < n; i++) if (k > limit*i && k <= limit*(i+1)) break;
char a = '0'+i+1;
status[i] = false;
k -= limit*i;
string str = "";
return find(str + a, n, k, status);
}
};