Algorithm/src/main/java/backtrack/SubsetsWithDup.java

53 lines
1.8 KiB
Java
Raw Normal View History

2025-03-28 17:37:12 +08:00
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 {
2025-07-05 18:04:10 +08:00
2025-03-28 17:37:12 +08:00
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
// 排序数组,使重复元素相邻,便于剪枝
Arrays.sort(nums);
backtrack(res, path, nums, 0);
return res;
}
void backtrack(List<List<Integer>> res, List<Integer> 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();
2025-07-05 18:04:10 +08:00
int[] nums = {1, 2, 3};
2025-03-28 17:37:12 +08:00
List<List<Integer>> subsets = solution.subsetsWithDup(nums);
System.out.println(subsets);
// 输出:[[], [1], [1, 2], [1, 2, 2], [2], [2, 2]]
}
}