标签:
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