给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets-ii
(1)回溯
在做本题之前,可以先了解LeetCode_回溯_中等_78.子集,这两题十分类似,只不过本题中的元素可能重复,而78.子集这题中的元素不重复。那么现在的关键在于如何去掉/避免重复的子集。我们可以考虑现将数组 nums 进行排序,这样可以将相等的元素排在一起。然后在回溯过程中的每次做选择前,先对要作用的元素进行判断,如果当前元素与前一个作用的元素相等,则说明当前元素是一个重复元素,因此跳过对该元素的操作。
//思路1————回溯
class Solution {
//res用于保存最终的结果
List<List<Integer>> res = new LinkedList<>();
//track用于记录回溯的路径
LinkedList<Integer> track = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
//对数组 nums 进行升序排序
Arrays.sort(nums);
backtrack(nums, 0);
return res;
}
public void backtrack(int[] nums, int start) {
res.add(new LinkedList(track));
//回溯算法框架
for (int i = start; i < nums.length; i++) {
//去除重复元素对生成的子集的影响
if (i > start && nums[i] == nums[i - 1]) {
continue;
}
//做选择
track.add(nums[i]);
backtrack(nums, i + 1);
//撤销选择
track.removeLast();
}
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43004044/article/details/120073991
内容来源于网络,如有侵权,请联系作者删除!