zoukankan      html  css  js  c++  java
  • LeetCode 78. Subsets(子集合)

    Given a set of distinct integers, nums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

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

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

    题目标签:Array

    方法 1:

      题目给了我们一个nums array,让我们找到所有的子集合。看到这种要找到所有的可能性的题目一般都要用到递归。我们设一个List List res,先把 [ ] 加入res。接着我们来根据原题中的例子来看一下。

      [1, 2, 3]

      我们依次把每一个数字的index,放到递归function 里去, 还要给一个 new ArrayList<>() 叫list 放到function 里。在递归function里,对于每一个index,首先把这个index 的数字加入list,然后把list 加入res 里。接着遍历它之后的所有数字,对于每一个数字,建立一个新的new ArrayList<>() 把这个list的值存入新的,继续递归下去。直到拿到的index 已经是最后一个数字了,把自己加入list,把list 加入res之后,直接跳过遍历,因为后面没有数字了,就返回了。我们来看一下例子

      

          [1]          [2]          [3]

            /                       /                     

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

               /

      [1,2,3]

    顺序为[ [ ], [1], [1,2], [1,2,3], [1,3], [2], [2,3], [3] ]

      

    Java Solution 1:

    Runtime beats 23.24% 

    完成日期:07/24/2017

    关键词:Array

    关键点:递归

     1 public class Solution 
     2 {
     3     List<List<Integer>> res = new ArrayList<>();
     4     
     5     public List<List<Integer>> subsets(int[] nums) 
     6     {
     7         List<Integer> empty = new ArrayList<>();
     8         res.add(empty);
     9         
    10         if(nums == null || nums.length == 0)
    11             return res;
    12         
    13         // sort nums array
    14         Arrays.sort(nums);
    15         
    16         // pass each number into findSubset
    17         for(int i=0; i<nums.length; i++)
    18             findSubset(i, nums, new ArrayList<>());
    19    
    20         return res;
    21     }
    22     
    23     public void findSubset(int begin, int[] nums, List<Integer> list)
    24     {
    25         // add nums[begin] into list
    26         list.add(nums[begin]);
    27         
    28         // add this list into res
    29         res.add(list);
    30         
    31         // pass rest numbers to findSubset with list starting from [begin...
    32         for(int i=begin+1; i<nums.length; i++)
    33         {
    34             List<Integer> temp = new ArrayList<>();
    35             temp.addAll(list);
    36             
    37             findSubset(i, nums, temp);
    38         }
    39         
    40         return;
    41     }
    42 }

    参考资料:N/A

    方法 2:

      基本的原理和方法1一样,只不过在方法2中,可以利用list 的remove 把最后一个数字去除,然后继续与剩下的数字组成subset。这样的话就可以不需要在subsets function里利用for loop把每一个数字pass 给helper function了。方法 2 更加清晰简介,具体看code。

    Java Solution 2:

    Runtime beats 23.24% 

    完成日期:08/25/2017

    关键词:Array

    关键点:递归,当新的递归返回的时候把tmpRes list里的最后一个数字去除

     1 public class Solution 
     2 {
     3     public List<List<Integer>> subsets(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 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             tmpRes.add(nums[i]);
    27             helper(res, tmpRes, i+1, nums);
    28             tmpRes.remove(tmpRes.size()-1);
    29         }
    30     }
    31 }

    参考资料:

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

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

  • 相关阅读:
    C++ std::map::erase用法及其陷阱
    写在分类之首-----to do list!
    Gradle系列教材(译)
    Android进阶-UIL分析
    ArrayList源码解析
    Android进阶-MVP
    高质量代码-树的子结构
    高质量代码-并和链表
    高质量代码-翻转链表
    高质量代码-链表中倒数第k个结点
  • 原文地址:https://www.cnblogs.com/jimmycheng/p/7232850.html
Copyright © 2011-2022 走看看