Permutation Sequence
hard 原题链接:https://leetcode.com/problems/permutation-sequence/
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 for n = 3:
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
例子
Input: n = 3, k = 3
Output: "213"
Input: n = 4, k = 9
Output: "2314"
Note
Given n will be between 1 and 9 inclusive.
Given k will be between 1 and n! inclusive.
解法一
class Solution {
public:
string getPermutation(int n, int k) {
string s = "", res = "";
vector<int>factorial(n + 1, 1);
int sum = 1;
for(int i = 1; i <= n; i++){
s.push_back(i + '0');
sum *= i;
factorial[i] = sum;
}
k--;
for(int i = 1; i <= n; i++){
int index = k / factorial[n - i];
res.push_back(s[index]);
s.erase(s.begin() + index);
k %= factorial[n - i];
}
return res;
}
};
The approach is mathematical. The idea is to keep selecting a digit and eliminating it from further selection based on value of K.
For example:
Given, N = 4, K = 9
There are 6 numbers starting with 1: 1234, 1243, 1324, 1342, 1423, 1432 There are 6 numbers starting with 2: 2134, 2143, 2314, 2341, 2413, 2431 Similarly, there are 6 numbers starting with 3 and 6 numbers starting with 4.
This is because when we have chosen one place out of 4 places (as N=4), there are 3 places remaining to be filled and those 3 places can be filled in 6 ways or (N-1)! ways.
So, we have to keep identifying which digit to choose.
Initially, we have to choose a digit from {1,2,3,4}.
Since K = 9, meaning it belongs to second set of six numbers and hence, would begin with 2.
Now, first place is chosen as 2 and output string becomes "2". This means we have eliminated 6 choices starting with 1 (1234, 1243, 1324, 1342, 1423, 1432).
Now, K would be updated as K = 9 - 6 = 3.
We now have to identify remaining 3 places with the digits {1,3,4} and with K = 3.
There are 2 numbers starting with 1: 134, 143 There are 2 numbers starting with 3: 314, 341 There are 2 numbers starting with 4: 413, 431
This is because when we have chosen one place out of 3 available places, there are 2 places remaining to be filled and those 2 places can be filled in 2 ways.
Since, K = 3, meaning it belongs to second set of two numbers and hence, answer would be appended with "3" and output string becomes "23". This means we have eliminated 2 choices starting with 1 (134, 143).
Now, K would be updated as K = 3 - 2 = 1.
We now have to identify remaining 2 places with the digits {1,4} with K = 1.
There is 1 number starting with 1: 14 There is 1 number starting with 4: 41
This is because when we have chosen one place out of 2 available places, there is only 1 place remaining to be filled and that 1 place can be only be filled in 1 ways.
Since, K = 1, meaning it belongs to first set of one number and hence, answer would be appended with "14" and output string becomes "2314".
Therefore, final answer becomes "2314".
解法二
class Solution {
public:
string getPermutation(int n, int k) {
string s = "";
for(int i = 1; i <= n; i++) s.push_back(i + '0');
while(--k) next_permutation(s.begin(), s.end());
return s;
}
};
解法三 backtracking
class Solution {
public:
string getPermutation(int n, int k) {
string s = "", res = "";
for(int i = 1; i <= n; i++) s.push_back(i + '0');
string path = s;
int count = 0;
DFS(s, 0, count, n, k, path, res);
return res;
}
void DFS(string& s, int pos, int& count, int n, int k, string& path, string& res){
if(count >= k || pos == n){
if(++count == k) res = path;
return;
}
for(int i = 0; i < n; i++){
if(s[i] == '0') continue;
path[pos] = s[i];
s[i] = '0';
DFS(s, pos + 1, count, n, k, path, res);
s[i] = path[pos];
}
}
};
最后更新于
这有帮助吗?