回溯题解——子集【LeetCode】二进制枚举法

78. 子集

✅ 一、算法逻辑讲解(逐步通顺解释)

这段代码的目标是:给定一个不含重复元素的整数数组 nums,返回其所有可能的子集(幂集)

步骤解析:

  1. 1 << len(nums)

    • 这是 2^n 的简写方式,表示子集的总数。

    • 因为一个长度为 n 的集合一共有 2^n 个子集。

  2. for i in range(1<<len(nums)):

    • i02^n - 1

    • 每个数字 i 的二进制表示就是一个子集的"选取方案",每一位表示该位置元素选不选。

      • 例如:nums = [a, b, c]i = 5 = 0b101 表示选 ac(第0和第2位是1)。
  3. [x for j, x in enumerate(nums) if i >> j & 1]

    • 枚举 nums 中的每个元素 x 及其下标 j

    • 如果 i 的第 j 位是 1,就说明这个元素被选入子集。

    • i >> j & 1 是判断第 j 位是否为1的经典写法。

  4. 将生成的子集 subsets 加入答案列表 ans 中。

  5. 返回所有子集的列表。


⭐ 二、核心思路

核心点是:用位运算枚举所有子集。

  • 将每一个子集的选取用一个 n 位二进制数表示(0 表示不选,1 表示选)。

  • 枚举 02^n - 1,每个整数的二进制形式唯一表示一个子集。

  • 位运算用于高效判断哪些元素被选中。

这是一种非常高效、简洁的生成子集的方式,尤其适用于集合元素较少(如 n ≤ 20)的场景。

python 复制代码
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        ans = []
        for i in range(1<<len(nums)):
            subsets = [x for j,x in enumerate(nums) if i>>j&1]
            ans.append(subsets)
        return ans

⏱ 三、时间复杂度分析

时间复杂度:O(n * 2^n)

  • 一共有 2^n 个子集。

  • 每个子集最多需要扫描 n 个元素来判断是否包含(通过 i >> j & 1 判断)。

  • 所以总的复杂度是:O(n * 2^n)

比如 nums = [1,2,3],就需要计算 2^3 = 8 个子集,每个最多判断 3 个位置。


💾 四、空间复杂度分析

空间复杂度:O(n * 2^n)(输出结果空间)

  • 每个子集可能长度为 n,最多有 2^n 个子集。

  • 所以总的空间用于保存输出结果是 O(n * 2^n)

额外空间(不含输出):O(n)

  • 每次生成一个子集使用一个列表(临时变量 subsets),最多长度为 n

  • 所以辅助空间是 O(n)

相关推荐
猿界零零七16 分钟前
pip install mxnet 报错解决方案
python·pip·mxnet
炸膛坦客33 分钟前
单片机/C/C++八股:(二十)指针常量和常量指针
c语言·开发语言·c++
I_LPL1 小时前
hot100贪心专题
数据结构·算法·leetcode·贪心
兑生1 小时前
【灵神题单·贪心】1481. 不同整数的最少数目 | 频率排序贪心 | Java
java·开发语言
颜酱1 小时前
DFS 岛屿系列题全解析
javascript·后端·算法
WolfGang0073212 小时前
代码随想录算法训练营 Day16 | 二叉树 part06
算法
炸膛坦客2 小时前
单片机/C/C++八股:(十九)栈和堆的区别?
c语言·开发语言·c++
零雲2 小时前
java面试:了解抽象类与接口么?讲一讲它们的区别
java·开发语言·面试
不只会拍照的程序猿2 小时前
《嵌入式AI筑基笔记02:Python数据类型01,从C的“硬核”到Python的“包容”》
人工智能·笔记·python
Jay_Franklin2 小时前
Quarto与Python集成使用
开发语言·python·markdown