本题需要在子集1的基础上去重,集合中可以有重复,但是求得的所有子集不能有重复。
属于树层去重,可以用used数组来表示是否重复过。
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
boolean[] used;
public List<List<Integer>> subsetsWithDup(int[] nums) {
if (nums.length == 0) {
res.add(path);
return res;
}
used = new boolean[nums.length];
//这步很重要,所有的去重都需要先排序,不排序做不出来
Arrays.sort(nums);
backtrack(nums, 0);
return res;
}
private void backtrack(int[] nums, int index) {
//这里先加入空集合
res.add(new ArrayList<>(path));
//这步可有可无,是判断结束条件的,但是如果没有这一步,for循环也会自动不满足条件结束
if (index >= nums.length) return;
for (int i = index; i < nums.length; i ++) {
//判断i>0且与上一个值相等且上一个值现在没用到,说明不是树枝上的相同的值,跳过这层循环
if (i > 0 && nums[i - 1] == nums[i] && !used[i - 1]) continue;
path.add(nums[i]);
used[i] = true;
backtrack(nums, i + 1);
used[i] = false;
path.removeLast();
}
}
}