给定一个可能具有重复数字的列表,返回其所有可能的子集
注意事项
- 子集中的每个元素都是非降序的
- 两个子集间的顺序是无关紧要的
- 解集中不能包含重复子集
样例
如果 S = [1,2,2]
,一个可能的答案为:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
思路:
第一种做法,递归加回溯。同一层中只要不选相同的数字,那么就不会出现重复的情况。(看似很有道理,可是证明它的正确性貌似没有这么容易,如何想到这种策略的呢?)
第二种做法,二进制加速(厉害了),利用hashset中不能包含相同的元素的特点,HashSet<arraylist> ans ,这样的结构为最后结果。
5个数字就有2的5次方种子集(不考虑重复),每一种情况就是一个数字,这个数字二进制表示的时候,有1的位要,为0的位不要。
第一种做法略
第二种做法:
import java.util.*; class Solution { /** * @param S: A set of numbers. * @return: A list of lists. All valid subsets. */ public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] S) { // write your code here Arrays.sort(S); HashSet<ArrayList<Integer>> ans=new HashSet<ArrayList<Integer>>(); int len=S.length; for(int i=0;i<Math.pow(2,len);i++){ ArrayList<Integer> temp=new ArrayList<Integer>(); int tem=i; for(int j=0;j<len;j++){ int tempint=tem&1; if(tempint==1){ temp.add(S[j]); } tem>>=1; } ans.add(temp); } return new ArrayList<ArrayList<Integer>>(ans); } }