• LeetCode 90. Subsets II (子集合之二)


    Given a collection of integers that might contain duplicates, nums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

    For example,
    If nums = [1,2,2], a solution is:

    [
      [2],
      [1],
      [1,2,2],
      [2,2],
      [1,2],
      []
    ]
    

    题目标签:Array

      题外话:搬完家后终于又回来刷题了,这次搬家整整用了2个星期,毕竟是从东北直接搬来了中南,光是开车就开了4天,每天开7小时,一共28小时。。。可是够累的。再加上各种杂事,看房租房,买家具,安装网络,换车牌。总算是差不多全搞定了,为了找一份工作也是不容易,那么回到刷题。

      这道题目和78. subset 方法二基本一样,只是多加了一个条件来防止duplicates subsets。那么如何防止duplicates subsets呢,我们来看原题例子 [1,2,2], 利用78. subset 的方法二, 我们可以得到 [ [ ], [1], [1,2], [1,2,2], [1,2], [2], [2,2], [2] ],其中有2个重复的子集合,[1,2] 和 [2]。根据方法二的code,我们可以发现,第二个 [1,2] 是在 for(int i=1; i<nums.length; i++)  这里面产生的。当 [1, 2, 2] 结束之后,remove 最后一个数字 变成 [1, 2],然后这个[1, 2]的 for loop 也结束了,返回后删除最后一个数字,变为 [1], 接着 for loop继续,移动到第二个2, 组成 [1,2] 产生的 重复子集合。 同样的,第二个 [2] 是在 for(int i=0; i<nums.length; i++) 这里面产生的, 当 [2, 2] 结束之后,删除最后一个数字变为[2],返回之后又删除最后一个数字变为 [ ], 然后for loop 继续移动到第二个2, 变为 [2] 产生的重复子集合。

      所以,重复的子集合都是在for loop里产生的,而且都是在第二个重复的数字那里。所以只需要多加一个条件 - 当遇到第二个重复的数字,直接跳过, 这样就可以在for loop 里避免重复的子集合。具体看code。

    Java Solution:

    Runtime beats 63.22% 

    完成日期:08/25/2017

    关键词:Array

    关键点:递归, 跳过第二个重复的数字来避免重复子集合

     1 public class Solution 
     2 {
     3     public List<List<Integer>> subsetsWithDup(int[] nums) 
     4     {
     5         // sort nums array
     6         Arrays.sort(nums);
     7         // create res
     8         List<List<Integer>> res = new ArrayList<>();
     9         // call recursion function
    10         helper(res, new ArrayList<>(), 0, nums);
    11         
    12         return res;
    13     }
    14     
    15     public static void helper(List<List<Integer>> res, List<Integer> tmpRes, int pos, int[] nums)
    16     {
    17         // here should be <= not just < because we need to add the new tmpRes in next recursion.
    18         // Therefore, we need one more bound to add tmpRes
    19         if(pos <= nums.length)
    20             res.add(new ArrayList<>(tmpRes));
    21         
    22         // once the new recursion is finished, remove the last number in the tmpRes and continue to 
    23         // add rest numbers to get new subsets
    24         for(int i=pos; i<nums.length; i++)
    25         {
    26             if(i > pos && nums[i] == nums[i-1]) // avoid duplicates
    27                 continue;
    28             
    29             tmpRes.add(nums[i]);
    30             helper(res, tmpRes, i+1, nums);
    31             tmpRes.remove(tmpRes.size()-1);
    32         }
    33     }
    34 }

    参考资料:

    https://discuss.leetcode.com/topic/22638/very-simple-and-fast-java-solution/4

    LeetCode 算法题目列表 - LeetCode Algorithms Questions List

  • 相关阅读:
    Visual Studio 2017 激活密钥
    jwt的ASP.NET MVC 身份验证
    Building a ASP.NET solution from commandline?从命令行构建 ASP.NET 解决方案?
    10 款更先进的开源命令行工具
    Cookie的Secure属性
    阻碍一个人成长的原因是什么?
    逃   离
    如何判断Javascript函数是否是Async函数
    【四百来块】小米RMMNT215NF显示器评测
    npm 中,n 是什么鬼?
  • 原文地址:https://www.cnblogs.com/jimmycheng/p/7433788.html
Copyright © 2020-2023  润新知