问题描述:
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 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.
Given k will be between 1 and n! inclusive.
Example 1:
Input: n = 3, k = 3
Output: "213"
Example 2:
Input: n = 4, k = 9
Output: "2314"
题源:here;完整实现:here
思路:
两种方案:1 暴力搜索;2 机智搜索。
方案1
我们同第46题一样,使用递归的方式生成排列,当遇到第k
个的时候返回。当然算法时间复杂度就是O(k)
,虽然是暴力搜索,但是却没有超时:),代码如下:
bool findK(string input, string output, string& result, int& count, int k){
if (input.size() == 0){
count++;
if (count == k){
result = output; return true;
}
return false;
}
for (int i = 0; i < input.size(); i++){
string tempInput = input, tempOutput = output;
tempOutput += tempInput[i];
tempInput.erase(i, 1);
if (findK(tempInput, tempOutput, result, count, k)) return true;
}
return false;
}
string getPermutation(int n, int k) {
string input, result;
for (int i = 0; i < n; i++) input += i+1+'0';
int count = 0;
findK(input, {}, result, count, k);
return result;
}
方案2
我们知道n
有n!
个排列,那n-1
有(n-1)!
个排列,当k>m*(n-1)!
时,说明第m
个位置的数应该放在最前面,希望你能理解:)。我们从第一个位置开始往后迭代,于是产生时间复杂度为O(n)
的算法,代码如下:
string getPermutation_2(int n, int k) {
string result, str;
vector<int> factorial(1, 0); int record = 1;
for (int i = 1; i <= n; i++){
str += i + '0';
record *= i; factorial.push_back(record);
}
for (int i = n - 1; i > 0; i--){
int idx = 0;
while (k>factorial[i]){
k -= factorial[i]; idx++;
}
result += str[idx]; str.erase(idx, 1);
}
result += str[0];
return result;
}