Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2]
, [1,2,1]
, and [2,1,1]
.
分析:
n个元素的序列,如果有i个重复的,那么将会有多少个序列呢?
不会此题,看别人答案之前的反思:
1,根据重复数没搞清楚会产生多少不同序列,3个重1个3序列,4个重2个6序列----迷茫
2,这里猜想即使有重复的数,next_permutation函数在此题的求法应该还是不变,因为我们始终是找到大于(没有等于)的第一对数
是否问题出在(1)中个数如何球呢?
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end()); //排序,第一个序列必须有序
vector<int> tmpnums=nums;
vector< vector<int> > result;
result.push_back(nums); //没有计算有多少个序列
while(true)
{
next_permutation(tmpnums.begin(), tmpnums.end());
if(tmpnums==nums)//说明求完了
break;
result.push_back(tmpnums); //原来一行一行的压入数据可以这样!!!
}
return result;
}
};
参考博客:http://blog.csdn.net/zhangxiao93/article/details/49356983
事后再来看这个问题:
可以看出,不事先知道会产生多少个数列组合也行,直接压入即可,直到和最初那个重复则跳出
先前太过纠结于会产生多少序列组合呢?
vector用法不足够熟悉
Given a collection of distinct 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]
.
思路首先:算了,还是用stl来做吧
不过还是再次来看next_permutation的原理:
但是比较明显的规律是:
1,升序为最小组合数,降序为最大组合数
2,某一个数的下一个数,就是比他大的最小组合数,比如123,下一个比他大的最小组合就是132,所以必须从低位处理
3,找到首个升序序列将其交换,然后逆置后面的数。比如:1234311
为1243311(首个升序已经交换),显然此数不是最小,并且后面的数逆置后才是最小的,即1243311为1243113。so,done!。
参考我的另一篇文章:http://blog.csdn.net/ebowtang/article/details/50450861
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
int col=nums.size();
int row=1;
for(int i=1;i<=col;i++)//求阶乘
row*=i;
vector< vector<int> > result(row);
for(int i=0;i < row ;i++)
result[i].resize(col);//设置数组的大小row行,col列
if(nums.empty())
return result;
vector<int> tmpnums=nums;
sort(tmpnums.begin(),tmpnums.end());//先排序
result[0]=tmpnums;
for(int i=1;i<row;i++)
{
next_permutation(tmpnums.begin(), tmpnums.end());
result[i]=tmpnums;
}
return result;
}
};
46,47两题可以用同样的代码AC
sort(nums.begin(),nums.end()); //排序,第一个序列必须有序
vector<int> tmpnums=nums;
vector< vector<int> > result;
result.push_back(nums); //没有计算有多少个序列
while(true)
{
next_permutation(tmpnums.begin(), tmpnums.end());
if(tmpnums==nums)//说明求完了
break;
result.push_back(tmpnums); //原来一行一行的压入数据可以这样!!!
}
return result;
附加函数:
next_permutation函数的具体实现:
void next_permutation(vector<int>& nums) {
if(nums.empty() || nums.size()==1)
return;
if(nums.size()==2)//测试案例中有两个元素的数组,简直了......
{
reverse(nums.begin(), nums.end());
return;
}
vector<int>::iterator ite1=nums.end()-1;
for(;;)
{
vector<int>::iterator ite2=ite1;
ite1--;
if(*ite1 < *ite2)
{
vector<int>::iterator itej=nums.end();
while(!(*ite1 < *--itej));
iter_swap(ite1,itej);//卧槽,找了老半天才知道错在这,迭代器交换两数的值,swap是数字直接交换
reverse(ite2,nums.end());
return;
}
if(ite1==nums.begin())
{
reverse(nums.begin(),nums.end());
return;
}
}
}
注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!
原文地址:http://blog.csdn.net/ebowtang/article/details/50489486
原作者博客:http://blog.csdn.net/ebowtang