leetcode hot100 78. 子集 递归回溯 medium 位运算法

题目 决策 递归结构
全排列 每层必须选一个 深度固定
子集 每个元素选/不选 深度递增

每个元素都有两种选择:选 或 不选。

python 复制代码
[]
├── [1]
│   ├── [1,2]
│   │   └── [1,2,3]
│   └── [1,3]
├── [2]
│   └── [2,3]
└── [3]

切片回溯

  • 排列:顺序重要 → 所有剩余都可选
  • 组合 / 子集:顺序不重要 → 只能往后选
问题类型 下一层还能选谁 代码
排列 除自己以外所有 nums:i + numsi+1:
子集 / 组合 只选后面的 numsi+1:
python 复制代码
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []

        def backtrack(nums, tmp):  #(待选列表,已有排列)
            res.append(tmp)   # 当前路径就是一个子集

            # 依次选择待选列表的元素,进入排列。
            for i in range(len(nums)):
                backtrack(nums[i+1:], tmp + [nums[i]])  # 子集顺序不重要,只能往后选

        backtrack(nums, [])
        return res

只能向后选:

python 复制代码
[]
├── [1]
│   ├── [1,2]
│   │   └── [1,2,3]
│   └── [1,3]
├── [2]
│   └── [2,3]
└── [3]

如果数组长度为 n,子集总数 = 2ⁿ

理论最优:O(n × 2ⁿ)

简单写法(位运算法)

每个元素可以选或不选,可以用二进制表示:

python 复制代码
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = [] 
        n = len(nums)

        # 数组长度为 n,子集总数 = 2ⁿ,则一共有2ⁿ种mask模板,2ⁿ=(1 << n)  (左移)
        for mask in range(1 << n):
            subset = []  # 这个mask产生的子集
            # 对每种mask,数组的n位
            for i in range(n):    # 对nums[0], nums[1], nums[2]...
                if mask & (1 << i):  # 判断该位是否为 1
                    subset.append(nums[i])  # 数字加入子集

            res.append(subset)  # 子集加入答案

        return res

时间复杂度

外层循环:2ⁿ

内层循环:n

方法 时间复杂度 额外空间
二进制位图 O(n·2ⁿ) O(n)
回溯 O(n·2ⁿ) O(n)
相关推荐
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
CoderYanger4 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
圣保罗的大教堂4 天前
leetcode 3524. 求出数组的 X 值 I 中等
leetcode
Tim_104 天前
【LeetCode】338、比特位计数
c++·算法·leetcode
mmmmath_34 天前
LeetCode.028.找出字符串中第一个匹配项的
数据结构·算法·leetcode
Navigator_Z4 天前
LeetCode //C - 1255. Maximum Score Words Formed by Letters
c语言·算法·leetcode
All for pursuit.4 天前
【栈-4】739.每日温度
数据结构·c++·算法·leetcode
开开心心就好4 天前
安卓手写文字生成工具,多种纸张一直免费
网络·网络协议·tcp/ip·leetcode·智能手机·电脑·模拟退火算法
All for pursuit.4 天前
【栈-5】84.柱状图中最大的矩形
数据结构·c++·算法·leetcode
圣保罗的大教堂4 天前
leetcode 1665. 完成所有任务的最少初始能量 中等
leetcode