当前位置: 首页 > news >正文

python-leetcode 55.子集

题目:

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

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


方法一:迭代法实现子集枚举

记原序列中元素的总数为 n,原序列中的每个数字 ai​ 的状态可能有两种,即「在子集中」和「不在子集中」。我们用 1 表示「在子集中」,0 表示不在子集中,,那么每一个子集可以对应一个长度为 n 的 0/1 序列,第 i 位表示 ai​ 是否在子集中。例如,n=3 ,a={5,2,9} 时:

可以发现 0/1 序列对应的二进制数正好从 0 到 2 n −1。我们可以枚举 mask∈[0,2 n −1],mask 的二进制表示是一个 0/1 序列,我们可以按照这个 0/1 序列在原集合当中取数。当我们枚举完所有 2 
n 个 mask,我们也就能构造出所有的子集。

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        ans=[] #一个空列表用于存储所有子集
        for i in range(1<<len(nums)):#位移操作,等价于 2 ** len(nums)
            subset=[]
            for j,x in enumerate(nums):# 遍历 nums,获取每个元素 x 及其索引 j
                if i>>j&1:# 如果 i 右移 j 位后与 1 按位与的结果为 1
                    subset.append(x)# 将当前元素 x 添加到 subset 中
            ans.append(subset)
        return ans
        
  • 时间复杂度:O(n2n),其中 n 为 nums 的长度。
  • 空间复杂度:O(1)。返回值的空间不计

方法二:递归

开始假设输出子集为空,遍历数组,对于数组中的每一个整数,每一步都向输出子集中所有子集添加这个整数,并生成新的子集。

dfs(0)
├── 包含 nums[0] = 1
│   └── dfs(1)
│       ├── 包含 nums[1] = 2
│       │   └── dfs(2)
│       │       ├── 包含 nums[2] = 3
│       │       │   └── dfs(3) → 添加 [1, 2, 3]
│       │       └── 不包含 nums[2] = 3
│       │           └── dfs(3) → 添加 [1, 2]
│       └── 不包含 nums[1] = 2
│           └── dfs(2)
│               ├── 包含 nums[2] = 3
│               │   └── dfs(3) → 添加 [1, 3]
│               └── 不包含 nums[2] = 3
│                   └── dfs(3) → 添加 [1]
└── 不包含 nums[0] = 1
    └── dfs(1)
        ├── 包含 nums[1] = 2
        │   └── dfs(2)
        │       ├── 包含 nums[2] = 3
        │       │   └── dfs(3) → 添加 [2, 3]
        │       └── 不包含 nums[2] = 3
        │           └── dfs(3) → 添加 [2]
        └── 不包含 nums[1] = 2
            └── dfs(2)
                ├── 包含 nums[2] = 3
                │   └── dfs(3) → 添加 [3]
                └── 不包含 nums[2] = 3
                    └── dfs(3) → 添加 []

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        t=[]  #用于存储当前子集
        ans=[] # 用于存储所有子集
        
        def dfs(cur): #定义深度优先搜索函数,cur 表示当前处理的索引
            if cur==len(nums): ## 如果当前索引等于 nums 的长度,说明已经处理完所有元素
                ans.append(t[:])# # 将当前子集 t 的拷贝添加到结果 ans 中
                return 
            t.append(nums[cur])#将当前元素 nums[cur] 添加到子集 t 中
            dfs(cur + 1)  # 递归处理下一个元素
            t.pop()# 回溯,移除当前元素,恢复子集 t
            dfs(cur+1)# 不包含当前元素,递归处理下一个元素
        dfs(0)
        return ans
        

时间复杂度:O(n×2**n )。一共 2 **n个状态,每种状态需要 O(n) 的时间来构造子集。

空间复杂度:O(n)。临时数组 t 的空间代价是 O(n),递归时栈空间的代价为 O(n)。

源自力扣官方题解
 

相关文章:

  • Flutter 按钮组件 ElevatedButton 详解
  • spring AOP学习
  • Matlab 汽车ABS实现模糊pid和pid控制
  • SQL语言的编译原理
  • SQLMesh宏操作符深度解析:掌握@star与@GENERATE_SURROGATE_KEY实战技巧
  • 重生之我在学Vue--第13天 Vue 3 单元测试实战指南
  • 【漫话机器学习系列】144.辛普森悖论(Simpson‘s Paradox)
  • 数学建模:MATLAB循环神经网络
  • 嵌入式八股RTOS与Linux---前言篇
  • YOLOv1到YOLOv12发展概述2025.3.17
  • 网络安全运维应急响应与溯源分析实战案例
  • MyBatis 如何创建 SqlSession 对象的?
  • Oracle静默安装方法
  • 再学:abi编码 地址类型与底层调用
  • 烽火HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包及注意点说明
  • C++和标准库速成(五)——C风格的数组、std::array、std::vector、std::pair和std::optional
  • Ruby 命令行选项
  • S32K144入门笔记(十三):LPIT的API函数解读
  • PostgreSQL 权限管理详解
  • 用旧的手机搭建 MQTT Broker-Node_red
  • 夜读丨跷脚牛肉乐翘脚
  • 专访|首夺天元头衔创生涯历史,王星昊打算一步一步慢慢来
  • 上海乐高乐园建设进入最后冲刺,开园限量纪念年卡将于5月开售
  • 餐饮店直播顾客用餐,律师:公共场所并非无隐私,需对方同意
  • 国家卫健委:工作相关肌肉骨骼疾病、精神和行为障碍成职业健康新挑战
  • 黄仁勋访华期间表示希望继续与中国合作,贸促会回应