zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
  • 相关阅读:
    二、网络基础
    Ado.net
    LINQ
    C#[抽象类,接口]
    自定义类库,并引用
    c#重点[封装,继承,多肽]
    c#重点[集合类型]异常,数组,集合ArrayList,List<>,hashTable,hashtable泛型(Dictionary)
    c#重点[数据类型,构造方法,变量,变量,运算符,装箱,拆箱]
    .net reflector激活
    sqlsever备份,还原和导入导出方法
  • 原文地址:https://www.cnblogs.com/qscgy/p/14604489.html
Copyright © 2011-2022 走看看