标签:
Given a collection of numbers, return all possible permutations.
For example,
[1,2,3] have
the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2],
and [3,2,1].
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
vector<vector<int>> temp1;
int length=nums.size();
if (length<=1)
{
res.push_back(nums);
return res;
}
vector<int> cur;
vector<int>temp;
for (int i=0;i<length;i++)
{
cur=nums;
cur.erase(cur.begin()+i);
temp1=permute(cur);
for (int j=0;j<temp1.size();j++)
{
temp=temp1[j];
temp.insert(temp.begin(),*(nums.begin()+i));
res.push_back(temp);
}
}
return res;
}
};递归方法不好理解,其中res,length都是每次调用,重新生成的。为了便于理解给出下面递归表示图:对于第k层节点来说,就是交换固定了前面 k-1 位,然后分别 swap(k,k), swap(k, k+1) , swap(k, k+2) ...
例如上图中的第2层,固定了第一位(即1),然后分别交换第2,3位。我们用一个三维矩阵Matrix存储上图的树,代码如下:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
if (nums.size()==1)
{
res.push_back(nums);
return res;
}
vector<vector<vector<int>>> maxtrix;
vector<vector<int>> temp;
temp.push_back(nums);
maxtrix.push_back(temp);
for (int i=0;i<nums.size()-1;i++)
{
temp=maxtrix[i];
vector<vector<int>> temp1;
for (int j=0;j<temp.size();j++)
{
temp1.push_back(temp[j]);
vector<int> element;
for (int t=i+1;t<nums.size();t++)
{
element=temp[j];
int tt=element[i];
element[i]=element[t];
element[t]=tt;
temp1.push_back(element);
}
}
maxtrix.push_back(temp1);
}
res=maxtrix[maxtrix.size()-1];
return res;
}
};
本质就是把N个for改成while的方法,很多把recursive的code改成iterative的code都会用到这样的方法,这个方法在编程之美里面的“电话号码”那一节提到过,参考我的博客http://blog.csdn.net/sinat_24520925/article/details/46413349。
举个例子来说吧
如果我想求1,2,3,4的全排列
偶的思路就是建一个特殊的数,它的进位方法是 3, 2, 1, 0
所以,这个数的++过程就是
0000 -> 0010 -> 0100 -> 0110 ->0200 -> 0210 ->
1000 -> 1010 -> 1100 -> 1110 ->1200 -> 1210 ->
2000 -> 2010 -> 2100 -> 2110 ->2200 -> 2210 ->
3000 -> 3010 -> 3100 -> 3110 ->3200 -> 3210
哇哈哈哈,刚好是24个!
然后捏? b0 b1 b2 b3就代表在当前剩下的数字中选择第bi个
哇!好复杂。。。
比如0210
0: 在1234中选择第0个,就是1
2: 在234中选择滴2个,就是4
1: 在23中选择第1个,就是3
0: 在2中选择第0个,就是2
所以0210对应点就是 1432。
相当于电话号码中0,1,2,3就是电话号码的各个数,1432就是对应的字母。在本题中,我们是要输出一定长度数组的所有排列组合,相当于此数组中的每个值就是一个电话号码,我们要找到,此电话号码对应的所有字母。参考http://blog.csdn.net/sinat_24520925/article/details/46413349的代码,本题的代码如下:
class Solution {
public:
int factorial(int n){
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
void renew_answer(vector<int> &p, const vector<int> &bound){
int i = p.size()-1;
while(i >= 0){
if(p[i] < bound[i]){
p[i]++;
break;
}else{
p[i] = 0;
i--;
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
int N=nums.size();
if (N==1)
{
res.push_back(nums);
return res;
}
vector<int> total(N,0);
for(int i=0;i<N;i++)
{
total[i]=N-1-i;
}
vector<int>answer(N,0);
vector<int>yuan_nums;
vector<int>temp;
yuan_nums=nums;
temp=nums;
for(int i = 0; i < factorial(N); i++)
{
nums=yuan_nums;
for(int j=0;j<N;j++)
{
temp[j]=nums[answer[j]];
nums.erase(nums.begin()+answer[j]);
}
res.push_back(temp);
renew_answer(answer,total);
}
return res;
}
};标签:
原文地址:http://blog.csdn.net/sinat_24520925/article/details/46413835