<LeetCode OJ> 47/46 Permutations (II / I)

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用法不足够熟悉




46. Permutations

Total Accepted: 81495  Total Submissions: 239854  Difficulty: Medium

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值