给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
class Solution {
HashSet<List<Integer>> hash=new HashSet<>();
List<Integer> temp=new ArrayList<>();
int[] nums;
public List<List<Integer>> subsetsWithDup(int[] nums) {
this.nums=nums;
Arrays.sort(nums);
backtrack(0);
List<List<Integer>> ans=new ArrayList<>();
for(List<Integer> t:hash) ans.add(t);
return ans;
}
public void backtrack(int index){
if(index==nums.length){
hash.add(new ArrayList<>(temp));
return;
}
//选或者不选
//左子树
temp.add(nums[index]);
backtrack(index+1);
temp.remove(temp.size()-1);
//右子树
backtrack(index+1);
}
}
注意这里的回溯算法里面没有结束条件,不必等到start==length时才结束
class Solution {
HashSet<List<Integer>> hash=new HashSet<>();
List<Integer> temp=new ArrayList<>();
int[] nums;
public List<List<Integer>> subsetsWithDup(int[] nums) {
this.nums=nums;
Arrays.sort(nums);
backtrack(0);
List<List<Integer>> ans=new ArrayList<>();
for(List<Integer> t:hash) ans.add(t);
return ans;
}
public void backtrack(int start){
hash.add(new ArrayList<>(temp));
for(int i=start;i<nums.length;i++){
temp.add(nums[i]);
backtrack(i+1);
temp.remove(temp.size()-1);
}
}
}
class Solution {
List<List<Integer>> ans=new ArrayList<>();
List<Integer> temp=new ArrayList<>();
int[] nums;
public List<List<Integer>> subsetsWithDup(int[] nums) {
this.nums=nums;
Arrays.sort(nums);
backtrack(0);
return ans;
}
public void backtrack(int start){
ans.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]);
backtrack(i+1);
temp.remove(temp.size()-1);
}
}
}