package backtrack; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 题目: 90. 子集 II (subsetsWithDup) * 描述:给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的 子集(幂集)。 * 解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。 示例 1: 输入:nums = [1,2,2] 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]] * 链接:https://leetcode.cn/problems/subsets-ii/ */ //不会,有点难 public class SubsetsWithDup { public List> subsetsWithDup(int[] nums) { List> res = new ArrayList<>(); List path = new ArrayList<>(); // 排序数组,使重复元素相邻,便于剪枝 Arrays.sort(nums); backtrack(res, path, nums, 0); return res; } void backtrack(List> res, List path, int[] nums, int start) { // 每次递归都将当前路径加入结果,注意:空集也会被加入 res.add(new ArrayList<>(path)); for (int i = start; i < nums.length; i++) { // 如果当前数字和前一个数字相同,并且前一个数字没有被选取(在本层中出现过),则跳过 if (i > start && nums[i] == nums[i - 1]) { continue; } path.add(nums[i]); backtrack(res, path, nums, i + 1); path.remove(path.size() - 1); } } // 测试方法 public static void main(String[] args) { SubsetsWithDup solution = new SubsetsWithDup(); int[] nums = {1, 2, 3}; List> subsets = solution.subsetsWithDup(nums); System.out.println(subsets); // 输出:[[], [1], [1, 2], [1, 2, 2], [2], [2, 2]] } }