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