链接:https://oj.leetcode.com/problems/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.
解法一:
DFS,超时。
代码如下:
class Solution {
public:
string getPermutation(int n, int k) {
if( n <= 0) return "";
string result;
num = 0;
vector<bool> flag(n+1, false);
dfs(n, 0, k, flag, "", result);
return result;
}
void dfs(int n, int step, int k, vector<bool> &flag, string path, string &result)
{
if( step == n )
{
num++;
if( num == k )
result = path;
return;
}
for(int i=1; i <= n; ++i)
{
if( !flag[i] )
{
flag[i] = true;
string nextpath(path);
nextpath.append(1, '0' + i);
dfs( n, step+1, k, flag, nextpath, result);
flag[i] = false;
}
if( result.size() > 0)
return;
}
}
private:
int num;
};
方法二
通过数学计算直接求的,时间复杂度 O(n^2).Accept
这个自己发现的,不知道有没有学术名字,如果那位仁兄知道,请不吝赐教,谢谢了。
通过分析可以发现,第n位的n个数,以每一个数开始的数都有(n-1)!个,因此我可以通过计算当前要取的第kth数,属于那个区间,即可得到第n位的值,
递归下去即可得到完整的结果。
代码如下:
string getPermutation(int n, int k) {
if( n <= 0 ) return "";
int totalNum = 1;
int count = 1;
while( count <= n )
totalNum *= count++;
if( k > totalNum || k <= 0)
return "";
string result;
vector<bool> flag( n+1, false);
for(int i=n; i > 0; --i)
{
int nextNum = totalNum/i;
int nextIndex = (k - 1) / nextNum + 1;
count = 0;
for(int j=1; j <= n; ++j)
{
if( !flag[j] )
count++;
if( count == nextIndex){
flag[j] = true;
result.append(1, j + '0');
break;
}
}
k -= nextNum * ( nextIndex - 1);
totalNum = nextNum;
}
return result;
}