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.
我的方法从高位到低位逐位确定数字。
以图例n=3进行说明:
构建数组v={1,2,3}
确定最高位:
ind=(k-1)/2
注:分母2是指每个最高位持续的排列数。由于除了最高位之外还有n-1=2位,一共可以出现2!种排列。
ind指的是所求的第k个排列会落在哪一个最高位的覆盖范围内。
k==1,2时,ind==0,最高位为v[ind]==1
k==3,4时,ind==1,最高位为v[ind]==2
k==5,6时,ind==2,最高位为v[ind]==3
其余数位如上思路逐位确定。
注意:
1、k的更新。k-=ind*fac(n-1),例如当k=1和2时,第二次的k就不变,当k=3或4时,第二次的k就应该等于1或2,也就是跳过以1开头的排列后,索要求得排列是第1个或第2个。(这块儿还有些绕,理解的不够)
2、vector<int> v的更新。将已经放好的数字,用它后面未放置的数字覆盖,然后将vector的最后一个元素pop掉。
//http://www.cnblogs.com/ganganloveu/p/4156188.html
//http://www.cnblogs.com/friends-wf/p/3676848.html
class Solution {
public:
int fac(int n)
{
int ret = 1;
while(n)
{
ret *=n;
n--;
}
return ret;
}
string getPermutation(int n, int k) {
string ret;
vector<int> v(n);
for(int i = 0;i< n;i++)
{
v[i] = i + 1;
}
while(n)
{
int ind = (k-1)/fac(n-1);
ret+=(v[ind]+'0');
k-=ind*fac(n-1);
for(int i = ind+1;i<n;i++)
{
v[i-1] = v[i];
}
v.pop_back();
n--;
}
return ret;
}
};
与组合数一样,简单构造法(Base Case and Build approach )非常管用。假设字符串S,以字符序列表示。
方法1:从前n-1个字符的排列构造
基本情况:第一个字符的排列
的排列只有一种,即
情况:的排列
情况:的 排列
情况:的排列
这是第一个有趣的情况。我们如何从的所有排列得到的所有排列?
的每一个排列代表的一个排序。例如,表示排序。
因此,如果我们拿出的所有排列,并将加入到所有可能的位置,我们就可以得到的所有排列。
class Permutation {
public:
vector<string> getPermutation(string A) {
// write code here
vector<string> ret;
if(A.length() == 0)
{
string tmp="";
ret.push_back(tmp);
return ret;
}
char firstCh = A[0];
string remainderA = A.substr(1);
vector<string> remainderRet = getPermutation(remainderA);
for(vector<string>::iterator it = remainderRet.begin();it!= remainderRet.end();++it)
{
for(int i = 0;i<=it->length();++i)
{
string tmp(*it);
tmp.insert(i,1,firstCh);
ret.push_back(tmp);
}
}
sort(ret.begin(),ret.end(),greater<string>());
return ret;
}
};
全排列,昨天正好刚在组合数学课上学了,自己尝试着写了一把,自己跑用例,结果是正确的,但是oj一直超时。代码如下
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int> > res;
if(num.empty())
return res;
if(num.size() == 1)
{
res.push_back(num);
return res;
}
sort(num.begin(),num.end());
res.push_back(num);
vector<int> tmp = num;
reverse(tmp.begin(),tmp.end());
while(num != tmp)
{
nextPermute(num);
res.push_back(num);
}
return res;
}
void nextPermute(vector<int> num)
{
int iMax;
for(int i = num.size() - 1;i >= 1;i--)
if(num[i-1] < num[i])
{
iMax = i;
break;
}
int jMax;
for(int j = num.size() -1 ;j >= iMax;j--)
if(num[iMax -1] < num[j])
{
jMax = j;
break;
}
swap(num[iMax -1],num[jMax]);
reverse(num.begin()+iMax,num.end());
}
};
修正后的代码,ac
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int> > res;
sort(num.begin(),num.end());
vector<int> tmp = num;
do{
res.push_back(num);
nextPermutation(num);
}while(num != tmp);
return res;
}
void nextPermutation(vector<int> &num) {
int iMax = -1;
for(int i = num.size() - 1;i >= 1;i--)
if(num[i-1] < num[i])
{
iMax = i;
break;
}
int jMax = -1;
for(int j = num.size() -1 ;j >= iMax;j--)
if(num[iMax -1] < num[j])
{
jMax = j;
break;
}
if(iMax != -1 and jMax != -1)
{
swap(num[iMax -1],num[jMax]);
reverse(num.begin()+iMax,num.end());
}
//f such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
else
reverse(num.begin(),num.end());
}
};
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int> > res;
sort(num.begin(),num.end());
do{
res.push_back(num);
}while(next_permutation(num.begin(),num.end()));
return res;
}
};