problem:
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]
.
thinking:
(1)之前写过求一个序列的下一个排列组合,这里就是应用求下一个排列的函数来输出所有可能的排列组合
(2)也可以调用STL的next_permutation()函数,这里我自己重新实现它
(3)题目标签提示使用回溯法,也可行,采用深度优先搜索算法
code:
dfs方法:
class Solution { public: vector<vector<int> > permute(vector<int> &num) { vector<vector<int> > ret; dfs(ret, num, 0); return ret; } void dfs(vector<vector<int> >& ret, vector<int>& num, int cur) { if(num.size() == cur) { ret.push_back(num); } else { for(int i = cur; i < num.size(); ++i) { swap(num[cur], num[i]); dfs(ret, num, cur+1); swap(num[cur], num[i]); } } } };
class Solution { public: vector<vector<int> > permute(vector<int> &num) { vector<vector<int> > ret; vector<int> tmp; int n = num.size(); int m=1; if(num.size()<2) { ret.push_back(num); return ret; } sort(num.begin(),num.end()); while(n) { m*=n; n--; } ret.push_back(num);//先插入排序好的序列 for(int i=1;i<m;i++)//m-1个 { tmp = my_next_permutation(num); ret.push_back(tmp); num=tmp; } return ret; } protected: /* *思路:从后往前比较,比如1-2-3,则直接反转后两位得到1-3-2 *对于1-2-4-3,则从后往前比较,发现2<4,则从后往前寻找第一个大于2的数3,交换得到1-3-4-2, * 再反转3之后的4-2部分得到:1-3-2-4 */ vector<int> my_next_permutation(vector<int> tmp) { vector<int>::iterator i = tmp.end()-1; vector<int>::iterator j=i-1; vector<int>::iterator swap=i; if(*i>*j) { iter_swap(i,j); return tmp; } while(i!=tmp.begin() && *j>*i) { j--; i--; } if(i==tmp.begin()) { reverse(tmp.begin(),tmp.end()); return tmp; } while(swap!=j && *swap<=*j) swap--; iter_swap(j,swap); reverse(i,tmp.end()); return tmp; } };