zoukankan      html  css  js  c++  java
  • LeetCode | 78. 子集

    给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    说明:解集不能包含重复的子集。

    示例:

    输入: nums = [1,2,3]
    输出:
    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    

    在它们的指数级解法中,要确保生成的结果 完整无冗余,有三种常用的方法:

    • 递归
    • 回溯
    • 基于二进制位掩码和对应位掩码之间的映射字典生成排列/组合/子集(位运算)

    位运算解法:

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>>ret;
            ret.push_back({});//压入空集
            int size = nums.size();
            int subsize = pow(2,size);
            int hash = 1;
            while(hash < subsize){
                vector<int>temp;
                for(int k = 0;k<size;++k){
                    int a = 1<<k;
                    if(a&hash){
                        temp.push_back(nums[k]);
                    }
                }
                ret.push_back(temp);
                ++hash;
            }
            return ret;
        }
    };
    

    原理:

    数组元素个数 为 3 ,那么 全部子集有 $2^3 = 8 $个, 使用位图表示,其中 位为 1 表示数组下标对应的位置。

    0 0 0 => { } //但要注意一下,这里我们是以 a = 1 << k 的所以并不会直接压空集进集合中

    0 0 1 => { 1 }

    0 1 0 => { 2 }

    0 1 1 => { 1, 2}

    1 0 0 => { 3 }

    1 0 1 =>{1 , 3}

    1 1 0 => {2 , 3}

    1 1 1 => {1, 2, 3}

    递归解法:

    class Solution {
    public:
        vector<vector<int>> result;
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<int> tmp(nums.size(), 0);
            subsets(nums, tmp, 0, 0);
            return result;
        }
    
        void subsets(vector<int>& nums, vector<int>& tmp, int pos, int t_pos) {
            if (pos >= nums.size()) {
                result.emplace_back(vector<int>(tmp.begin(), tmp.begin()+t_pos));
                return;
            }
            tmp[t_pos] = nums[pos];
            subsets(nums, tmp, pos + 1, t_pos+1);  // 取nums[pos]
            subsets(nums, tmp, pos + 1, t_pos);    // 不取nums[pos]
        }
    };
    

    回溯解法:

    /*
    to be continue;
    */
    
  • 相关阅读:
    Kendo
    过河
    数组分组(简单dp)
    Codeforces Round #604 (Div. 2)(A-E)
    HDU1253
    HDU1026
    linux常用命令(二) --目录操作
    linux常用命令(一)--ls
    hdu 1072
    Codeforces Round #597 (Div. 2)(A-D)
  • 原文地址:https://www.cnblogs.com/RioTian/p/12624820.html
Copyright © 2011-2022 走看看