problem:
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.
Backtracking Maththinking:
(1)直观想到调用next_permutation()函数,该函数STL已经实现,我自己也实现过(http://blog.csdn.net/hustyangju/article/details/44751293),因为next_permutation()函数的时间复杂度为O(n),所以调用该函数的时间复杂度为O(n*k),相当庞大,提交Time Limit Exceeded
(2)math 法
注意到排列组合的规律: n! = n*(n-1)!
将数组array[n] ={1,2,...,n} ,输出序列的第一位数字在array的下标index1等于?
index1 = (k-1)/n!
开始考虑第二位数字:
首先:k%=n!
index2 = k/(n-1)!
....
以此类推,直到求出第n位数字的下标indexn
(3)DFS法
视决定一位数字为 1 step,深度为n,每一步确定数字的方法同 方法2,所以DFS也很容易实现
code:
math法:
Accepted | 4 ms |
class Solution {
public:
string getPermutation(int n, int k) {
vector<int> tmp;
int count=1;
string str;
k--;
for(int i=1;i<=n;i++)
{
tmp.push_back(i);
count*=i;
}
for(int i = 0 ; i < n; i++)
{
vector<int>::iterator it=tmp.begin();
count = count/(n-i);
int selected = k / count;
k%=count;
str.push_back('0' + tmp[selected]);
tmp.erase(it+selected);
}
return str;
}
};
Accepted | 4 ms |
class Solution {
private:
string str;
public:
string getPermutation(int n, int k) {
vector<int> tmp;
str.clear();
int count=1;
k--;
for(int i=1;i<=n;i++)
{
tmp.push_back(i);
count*=i;
}
dfs(0,n,tmp,k,count);
return str;
}
protected:
void dfs(int dep,int n,vector<int> &tmp, int &k,int &count)
{
if(dep>=n)
return;
vector<int>::iterator it=tmp.begin();
count/=n-dep;
int index=k/count;
k%=count;
str.push_back('0' + tmp[index]);
tmp.erase(it+index);
dfs(dep+1,n,tmp,k,count);
}
};