回溯题解——子集【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)

相关推荐
地平线开发者5 小时前
J6B vio scenario sample
算法
SelectDB12 小时前
Apache Doris Python UDF:让 SQL 直接调用 Python 生态,支撑 Agent 时代复杂业务逻辑
大数据·数据库·python
BothSavage17 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn17 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽19 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
荣码19 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
金銀銅鐵1 天前
[Python] 基于欧几里得算法,实现分数约分计算器
python·数学
Lyn_Li1 天前
Kaggle Top 5 | 198只股票、200条数据的金融预测——BattleFin高分方案从零复现
python·kaggle·比赛复盘·金融预测