Leetcode 90. 子集 II

给你一个整数数组 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

解题思路

迭代法实现子集枚举

考虑数组 [1,2,2],选择前两个数,或者第一、三个数,都会得到相同的子集。

也就是说,对于当前选择的数 x,若前面有与其相同的数 y,且没有选择 y,此时包含 x 的子集,必然会出现在包含 y 的所有子集中。

我们可以通过判断这种情况,来避免生成重复的子集。代码实现时,可以先将数组排序;迭代时,若发现没有选择上一个数,且当前数字与上一个数相同,向下一个位置递归迭代时,当前递归路径下的集合不需要选取当前元数,以避免重复。

代码实现

java 复制代码
class Solution {
     public List<List<Integer>> subsetsWithDup(int[] nums) {
        Set<List<Integer>> r = new HashSet<>();
        Arrays.sort(nums);
        dfs23(nums, r, 0, new ArrayList<>());
        return new ArrayList<>(r);
    }

    private void dfs23(int[] nums, Set<List<Integer>> r, int i, List<Integer> t) {
        if (i == nums.length) {
            r.add(new ArrayList<>(t));
            return;
        }
        for (int j = i; j < nums.length; j++) {
            dfs23(nums, r, j + 1, t); // 不选取元素
            if (j > 0 && nums[j] == nums[j - 1] && (t.size() > 0 && t.get(t.size() - 1) != nums[j])) {
                continue;
            }
            t.add(nums[j]);  // 选取元素
            dfs23(nums, r, j+ 1, t);
            t.remove(t.size() - 1);
        }
    }
}
相关推荐
Black蜡笔小新7 小时前
自动化AI算法训练服务器DLTM助力医学影像分析进入AI智能分析新时代
人工智能·算法·自动化
手写码匠8 小时前
深入解析大模型架构之争:全能通用模型 vs 领域专精模型
人工智能·深度学习·算法·aigc
浅念-8 小时前
LeetCode 回溯算法题——综合练习
数据结构·c++·算法·leetcode·职场和发展·深度优先·dfs
列星随旋9 小时前
线段树和树状数组的学习
学习·算法
圣保罗的大教堂9 小时前
leetcode 61. 旋转链表 中等
leetcode
全糖可乐气泡水11 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
h_a_o777oah11 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师11 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
手写码匠13 小时前
Android 17 适配实战指南:新特性解读、隐私变更与迁移全攻略
人工智能·深度学习·算法·aigc