53 lines
1.8 KiB
Java
53 lines
1.8 KiB
Java
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<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();
|
||
int[] nums = {1, 2, 3};
|
||
List<List<Integer>> subsets = solution.subsetsWithDup(nums);
|
||
System.out.println(subsets);
|
||
// 输出:[[], [1], [1, 2], [1, 2, 2], [2], [2, 2]]
|
||
}
|
||
}
|