78. Subsets I & II
来源:互联网 发布:淘宝客如意投怎么设置 编辑:程序博客网 时间:2024/05/19 03:29
QUESTION
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], []]
THOUGHT I
利用位操作,很好理解,当某一位为1的时候代表可以加入到集合当中去。对于数组[1,2,3],可以用一个下标0和1表示是否选择该数字,0表示未选择,1表示选中,那么每一组3个0和1的组合表示一种选择,3位共有8种选择,分别是:
000 对应[] 001 对应[3] 010 对应[2] 011 对应[2,3] 100 … 101 110 111
那么上面为1的位表示数组中该位被选中。 那么只需要遍历0到1<< length中的数,判断每一个数中有那几位为1,为1的那几位即会构成一个子集中的一个元素。
CODE
public class Solution { public List<List<Integer>> subsets(int[] nums) { ArrayList<List<Integer>> result = new ArrayList<List<Integer>>(); for(int i = 0;i < 1 << nums.length;i++){ ArrayList<Integer> temp = new ArrayList<Integer>(); for(int j = 0;j < nums.length;j++){ if((i & (1 << j)) != 0 ) temp.add(nums[j]); } result.add(new ArrayList(temp)); } return result; }}
RESULT
runtime complexity is O(2^n),space complexity is O(1);
SPECIAL ATTENTION
- == 还有!= 的优先级要高于&;
== has higher priority than &. You might want to wrap your operations in () to specify your own priority.((a[0] & 1) == 0)Similarly for all parts of the if condition.
- 把一个List加入到另一个List当中去,如果List发生变化,存入的结果也会发生变化,也就是传址引用,我们的做法是new一个新的List;
- 注意阶段性空间的初始化位置问题;
THOUGHT II
基本思路循环+dfs,生成指定元素数目(0,1,2,…array.size()个元素)的组合。
CODE
public class Solution { public List<List<Integer>> subsets(int[] nums) { ArrayList<List<Integer>> result = new ArrayList<List<Integer>>(); ArrayList<Integer> temp = new ArrayList<Integer>(); result.add(temp); if(nums.length == 0) return result; for(int i = 1;i <= nums.length;i++){ dfs(result,temp,nums,i,0); } return result; } public void dfs(ArrayList<List<Integer>> result,ArrayList<Integer> temp,int[] nums,int len,int start){ if(temp.size() == len){//边界条件 result.add(new ArrayList<Integer>(temp)); return; } for(int i = start;i < nums.length;i++){ temp.add(nums[i]); dfs(result,temp,nums,len,i+1); temp.remove(temp.size() - 1); } }}
RESULT
递归类的时间复杂度不会算;
THOUGHT III 二刷
这里有一个通用的解法,适用于回溯问题A general approach to backtracking questions in Java (Subsets, Permutations, Combination Sum, Palindrome Partitioning)
CODE
public class Solution { public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> res = new ArrayList<>(); if(nums == null || nums.length == 0) return res; Arrays.sort(nums); List<Integer> tempList = new ArrayList<>(); helper(res,tempList,nums,0); return res; } private void helper(List<List<Integer>> res,List<Integer> tempList,int[] nums,int start){ res.add(new ArrayList<>(tempList)); for(int i = start;i < nums.length;i++){ tempList.add(nums[i]); helper(res,tempList,nums,i + 1); tempList.remove(tempList.size() - 1); } }}
QUESTION 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], []]
THOUGHTS
比上个解法多了一个排序,多了一个去重。这里不是很理解为什么不排序不能通过。没有要求从小到大输出啊。
CODE
public class Solution { public List<List<Integer>> subsetsWithDup(int[] nums) { ArrayList<List<Integer>> result = new ArrayList<List<Integer>>(); ArrayList<Integer> temp = new ArrayList<Integer>(); result.add(temp); if(nums.length == 0) return result; Arrays.sort(nums); for(int i = 1;i <= nums.length;i++){ dfs(result,temp,nums,i,0); } return result; } public void dfs(ArrayList<List<Integer>> result,ArrayList<Integer> temp,int[] nums,int len,int start){ if(temp.size() == len){//边界条件 result.add(new ArrayList<Integer>(temp)); return; } for(int i = start;i < nums.length;i++){ temp.add(nums[i]); dfs(result,temp,nums,len,i+1); temp.remove(temp.size() - 1); while(i<(nums.length - 1)&&nums[i] == nums[i+1]) { i++; } } }}
THOUGHT II
用回溯法来进行遍历,别忘了要先排序
CODE
public class Solution { public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> res = new ArrayList<>(); if(nums == null || nums.length == 0) return res; Arrays.sort(nums); List<Integer> temp = new ArrayList<>(); helper(res,temp,nums,0); return res; } private void helper(List<List<Integer>> res,List<Integer> temp,int[] nums,int start){ res.add(new ArrayList<>(temp)); for(int i = start;i < nums.length;i++){ if(i > start && nums[i] == nums[i - 1]) continue; temp.add(nums[i]); helper(res,temp,nums,i + 1); temp.remove(temp.size() - 1); } }}
- 78. Subsets I & II
- 78. Subsets I && 90. Subsets II
- 【LeetCode】Subsets I && II
- Subsets I, II
- [Leetcode]Subsets I&II
- LeetCode - Subsets I && II
- LeetCode | Subsets I,II
- LeetCode:Subsets I II
- leetcode -day31 Subsets I II
- 78. Subsets && 90. Subsets II
- 78. Subsets 90. Subsets II
- 78. Subsets &90. Subsets II
- 78. Subsets,90. Subsets II
- 78. Subsets && 90. Subsets II
- 78. Subsets 90. Subsets II
- 78. Subsets & 90. Subsets II
- LeetCode题解:Subsets I and II
- <LeetCode OJ> 78 / 90 Subsets (I / II)
- LightOJ-2991-线段树
- 获取select下拉框选中元素的值
- Java基础--数据类型,运算符,程序控制语句
- 说明
- Hive初探
- 78. Subsets I & II
- Dialog背景透明
- String常用方法
- matlab之repmat
- 单选框(RadioButton)和复选框(CheckBox)
- nrf51822蓝牙学习笔记之GAP(通用属性配置文件)解读(二)
- Java 数据库 第四章 使用DML语句更改数据
- 模拟库中的字符串处理函数
- Java拼接字符串时,去掉最后一个多余的逗号 .