• 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
    

    题解:

    • 回溯法
    class Solution {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            Arrays.sort(nums);
            Set<List<Integer>> ans = new HashSet<>();
            List<Integer> cur = new ArrayList<>();
            dfs(nums, 0, cur, ans);
            return new ArrayList<>(ans);
        }
    
        /**
         * @param nums 原输入数组
         * @param u 当前决策到原输入数组中的哪一位
         * @param cur 当前方案
         * @param ans 最终结果集
         */
        void dfs(int[] nums, int u, List<Integer> cur, Set<List<Integer>> ans) {
            // 所有位置都决策完成,将当前方案放入结果集
            if (nums.length == u) {
                ans.add(new ArrayList<>(cur));
                return;
            }
    
            // 选择当前位置的元素,往下决策
            cur.add(nums[u]);
            dfs(nums, u + 1, cur, ans);
    
            // 不选当前位置的元素(回溯),往下决策
            cur.remove(cur.size() - 1);
            dfs(nums, u + 1, cur, ans);
        }
    }
    

    时间复杂度:排序时间(O(nlogn)),爆搜复杂度为(O(2^n)),每个方案通过深拷贝存入答案,为(O(n)),整体时间复杂度为(O(n imes2^n))
    空间复杂度:总共有(2^n)个方案,每个方案最多占用(O(n))空间,整体为((n imes2^n))

    • 状态压缩
    class Solution {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            Arrays.sort(nums);
            int n = nums.length;
            Set<List<Integer>> ans = new HashSet<>();
            List<Integer> cur = new ArrayList<>();
            
            // 枚举 i 代表,枚举所有的选择方案状态
            // 例如 [1,2],我们有 []、[1]、[2]、[1,2] 几种方案,分别对应了 00、10、01、11 几种状态
            for (int i = 0; i < (1 << n); i++) {
                cur.clear();
                // 对当前状态进行诸位检查,如果当前状态为 1 代表被选择,加入当前方案中
                for (int j = 0; j < n; j++) {
                    int t = (i >> j) & 1;
                    if (t == 1) cur.add(nums[j]);
                }
                // 将当前方案中加入结果集
                ans.add(new ArrayList<>(cur));
            }
            return new ArrayList<>(ans);
        }
    }
    
  • 相关阅读:
    Vue 兄弟组件通信(不使用Vuex)
    vue2.0 #$emit,$on的使用
    Bootstrap栅格系统基本使用
    字体图标使用
    js事件委托
    帆布小球碰壁效果
    vuex -- vue的状态管理模式
    JavaScript --经典问题
    总结获取原生JS(javascript)基本操作
    git的基本操作
  • 原文地址:https://www.cnblogs.com/qscgy/p/14604489.html
Copyright © 2020-2023  润新知