含重复元素的子集生成

求解思路
当数组中存在重复元素时,暴力枚举会产生大量重复子集。这里把"是否选择某个元素"的问题,转化为"选择该元素几个"的问题,自然避免了重复。
代码实现详解
public static List<List<Integer>> subsetsWithDup(int[] nums) {List<List<Integer>> ans = new ArrayList<>();Arrays.sort(nums); // 排序让相同元素聚在一起f(nums, 0, new int[nums.length], 0, ans);return ans;
}public static void f(int[] nums, int i, int[] path, int size, List<List<Integer>> ans) {if (i == nums.length) {// 到达边界,收集当前路径ArrayList<Integer> cur = new ArrayList<>();for (int j = 0; j < size; j++) {cur.add(path[j]);}ans.add(cur);} else {// 找到下一组不同元素的起始位置int j = i + 1;while (j < nums.length && nums[i] == nums[j]) {j++;}// 决策1: 当前这组数,一个都不要f(nums, j, path, size, ans);// 决策2: 当前这组数,要1个、2个、3个...for (; i < j; i++) {path[size++] = nums[i];f(nums, j, path, size, ans);}}
}
如果觉得有帮助,欢迎点赞、关注、转发~
