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]);
}
}
}
};
next_permutation方法:
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;
}
};