Permutations I , II

24 篇文章 0 订阅
10 篇文章 0 订阅

Permutations

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],
  [3,2,1]
]

nums的每个数都与其后面的数交换,采用深度递归

class Solution {
//递归,每次调用时都将当前的数与后面的数交换
    void DFS(vector
   
   
    
     & nums, int start, vector
    
    
     
     
      
      > & r)
    {
        if(start>=nums.size()) r.push_back(nums);
        else
        {
            for(int i=start;i
      
      
       
       > permute(vector
       
       
         & nums) { int n=nums.size(); vector 
         
         
           > r; DFS(nums,0,r); return r; } }; 
          
         
       
      
      
     
     
    
    
   
   

void DFS(vector<int> & nums, int start, vector<vector<int>> & r)//注意这里是nums的引用传递

Permutations II

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],
  [2,1,1]
]

https://discuss.leetcode.com/topic/8831/a-simple-c-solution-in-only-20-lines/47

先将数组排好序,然后进行元素交换,这里排重是个问题。如果采用递归时,将nums进行引用传递,第i个递归内的第i+1个递归会改变nums的值,

swap(nums, start, i);
permutating(ans, Arrays.copyOf(nums, nums.length), start+1);
swap(nums, start, i);

这样只是交换回来,是无法恢复原样的,也会有重复。

通过的代码:

void DFS(vector<vector<int>>& r,vector<int>  nums,int start)//这里的nums是值传递。对于数组中的每个数如果前面没有与它重复的数,

那么它一定可以交换到当前迭代的首部,它后面的如果与他重复,就会被忽略,这样保证第i次迭代的首个元素不会有重复,然后再进行下一次迭代。

class Solution {
    //nums是值传递
    void DFS(vector
   
   
    
    
     
     >& r,vector
     
     
      
        nums,int start)
    {
        if(start==nums.size()-1)
        {
            r.push_back(nums);
            return ;
        }else
        {
            for(int i=start;i
      
      
       
       > permuteUnique(vector
       
       
         & nums) { sort(nums.begin(),nums.end()); vector 
         
         
           > r; DFS(r,nums,0); return r; } }; 
          
         
       
      
      
     
     
    
    
   
   
按照这里的值传递,举个例子,它的一次递归过程,发现下一次递归过程:它的后面3个元素也是排好序的

(1,2,2,3) (pos = 0, i = 0)

(2,1,2,3) (pos = 0, i = 1)

(2,1,2,3) (pos = 0, i =2) skipped, since array[0]=array[2]; //排重

(3,1,2,2) (pos = 0, i =3)

但按照引用传递的递归, 它的后面3个元素不是排好序的

(1,2,2,3) (pos = 0, i = 0)

(2,1,2,3) (pos = 0, i = 1)//1序列

(2,2,1,3) (pos = 0, i =2) //这回产生重复,下一次递归从pos=1开始,其子序列与上一个1序列产生的子序列一样

(3,2,2,1) (pos = 0, i =3)

如果排重的过滤条件为:if (nums[i] == nums[i - 1] && i != begin)也不行,排好序的队列,会在子递归的过程中失序,下次递归就无法排重了。

另一种解法:增加一个数组used,用来表示第i个数是否在该次迭代中用过,每次选一个元素加入到存储排列的vector<int>中;

这里排重通过nums[i]和nums[j]是否相等及used来确定。

class Solution {
    void DFS(vector
   
   
    
    
     
     >& r,vector
     
     
      
       & nums,vector
      
      
       
        & nu, vector
       
       
         &used) { if(nu.size()==nums.size()) { r.push_back(nu); return ; }else { for(int i=0;i 
        
          0&&nums[i]==nums[i-1] && used[i-1]) //这里用了used[i-1],可以理解为前面nums[i-1]已经用了,这个和它一样的 //nums[i]就可以直接跳过了,但是原版的是!used[i-1],两个都能通过,实在不能理解呢 continue; used[i]=true; nu.push_back(nums[i]); DFS(r,nums,nu,used); used[i]=false; nu.pop_back(); } } } public: vector 
          
          
            > permuteUnique(vector 
           
             & nums) { sort(nums.begin(),nums.end()); vector 
             
             
               > r; vector 
              
                used(nums.size(),false); vector 
               
                 nu; DFS(r,nums,nu,used); return r; } }; 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值