• 78 子集


    题目

    给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

    解集不能包含重复的子集。你可以按任意顺序返回解集。

    示例 1:

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

    输入:nums = [0]
    输出:[[],[0]]

    • 关于顺序

      • 如果想要每个子集中的数字有序,在开始递归前先对原数组排序
      • 如果想子集按照数字个数从小到大,选数字时先选择不选再选择选
    • 法一:递归枚举,对每个元素都进行选或不选

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> result;//记录最终结果
            vector<int> path;//记录每趟子集计算中的当前子集
            subsets(path, nums,0, result);//初始从第一个数字开始选
            return result;
        }
    
        void subsets(vector<int>& path, vector<int>& nums, int cur,vector<vector<int>> &result)
        {
        	//如果判断完所有的数字就把当前子集加入结果中
            if(cur==nums.size())
            {
                result.push_back(path);
                return;
            }
            //如果不选当前数字
            subsets(path,nums,cur+1, result);
            //如果选择当前数字
            path.push_back(nums[cur]);
            subsets(path,nums,cur+1,result);
            path.pop_back();//把path数组恢复原样
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 时间复杂度:O(2^n)

    • 空间复杂度O(n)

    • 思路

      • 对每个元素都选择要或不要,每当pandasn个元素后,将当前path中的数据存储到结果中
    • 法二:位向量法,递归枚举,使用bool数组记录选择

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> result;//记录结果
            vector<bool> selected(nums.size(),false);//记录是否使用当前数字
            subsets(selected, nums,0, result);
            return result;
        }
    	//依次对每个数字做选择,全部数字选择完后将子集记录到结果中
        void subsets(vector<bool>& selected, vector<int>& nums, int cur,vector<vector<int>> &result)
        {
            if(cur==nums.size())//记录当前子集
            {
                vector<int> path;
                //将selected中的数据转化为当前子集
                for(int i=0;i<nums.size();i++)
                    if(selected[i]==true) path.push_back(nums[i]);
                result.push_back(path);
                return;
            }
            selected[cur] = true;//选择当前数字,递归调用挑选下一个数字
            subsets(selected,nums,cur+1, result);
            selected[cur] = false;//不选择当前数字,递归调用挑选下一个数字
            subsets(selected,nums,cur+1,result);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 时间复杂度:O(2^n)

    • 空间复杂度O(n)

    • 该方法只能在没有重复数字时使用

    • 法三:二进制法,即位向量法的迭代版

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> result;
            vector<int> subset;
            int n=nums.size();
            for(int i=0; i<(1<<n); i++)//1<
            {
                for(int j=0; j<n; j++)//依次将每一个int转化为一个子集
                {
                    if(i&(1<<j)) subset.push_back(nums[j]);
                }
                result.push_back(subset);//子集加入到结果中
                subset.clear();//清空当前子集
            }
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 时间复杂度O(2^n)
    • 空间复杂度O(n)
    • 思路
      • 本方法的前提是:集合的元素个数不超过int类型的位数。
      • 用一个int中的每一位表示对应数组中元素是否选择。每个元素选择要或不要,一共有2^n种选法,对应在int中比1<
  • 相关阅读:
    微服务之流控、容错组件sentinel
    数据仓库为什么要分层建设?每一层的作用是什么?
    ModuleNotFoundError: No module named ‘office’ - Python自动化办公,常见问题【01】
    2001. 可互换矩形的组数-快速排序
    mmlab实现图像分类
    【前端打怪升级日志之CSS篇】position定位
    电子电器架构——智能座舱设备终端
    【vue】牛客专题训练02
    小程序Android的学生作业与提醒管理系统
    Chatgpt人工智能对话源码系统分享 带完整搭建教程
  • 原文地址:https://blog.csdn.net/weixin_45781228/article/details/126002285