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

相关推荐
大大杰哥1 分钟前
leetcode hot100(4)矩阵
算法·leetcode·矩阵
Fuyo_11194 分钟前
C++中的活字印刷术——模板·初阶
开发语言·c++·笔记
小白|5 分钟前
cmake:昇腾CANN构建系统完全指南
java·c++·算法
在角落发呆5 分钟前
跨越网络鸿沟:传统文件传输与现代内网穿透的奇妙交响
开发语言·php
nebula-AI6 分钟前
人工智能导论:模型与算法(未来发展与趋势)
人工智能·神经网络·算法·机器学习·量子计算·automl·类脑计算
炽烈小老头7 分钟前
【每天学习一点算法 2026/05/21】课程表
学习·算法
Season4509 分钟前
C++之模板元编程(前置知识 constexpr)
开发语言·c++
luoganttcc11 分钟前
大模型是否即将到达算法极限
算法
BU摆烂会噶11 分钟前
【LangGraph】House_Agent 实战(四):预定流程 —— 中断与人工干预
android·人工智能·python·langchain
AI玫瑰助手11 分钟前
Python运算符:比较运算符(等于不等等于大于小于)与返回值
android·开发语言·python