一天一道算法题(34):回溯法的经典例题(子集)

78. 子集

文章目录

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

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

示例 1:

text

复制代码
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

text

复制代码
输入:nums = [0]
输出:[[],[0]]

思路

  • 这道题和全排列一样,都是递归的经典题,但子集比全排列多了一个"顺序无关"的限制。全排列里 [1,2] 和 [2,1] 是两个答案,但子集里它们是同一个。所以这道题递归的核心就变成了:怎么保证下一层只从当前位置往后选。下面用回溯法写一下

- 回溯法

  • 这里我们用闭包的方式,不需要传结果集的指针

  • 使用到的参数有

    1. ans 用来记录结果集
    2. path 当前子集
    3. start 下一层枚举的起点
  • go

    go 复制代码
    func subsets(nums []int) [][]int {
        ans := make([][]int, 0)
        path := make([]int, 0)
        length := len(nums)
    
        var dfs func(start int)
        dfs = func(start int) {
            //每进入一层,当前 path 就是一个合法子集
            tmp := append([]int(nil), path...)
            ans = append(ans, tmp)
    
            //从 start 开始枚举,保证顺序不重复
            for i := start; i < length; i++ {
                path = append(path, nums[i])
                dfs(i + 1)
                //回溯
                path = path[:len(path)-1]
            }
        }
    
        dfs(0)
        return ans
    }
  • 还有一个容易踩的坑:ans = append(ans, path) 这样写是错的,因为 path 是复用的切片,后续 append 和截断会改到底层数组。必须像上面那样拷贝一份 tmp 再存

结语

本文是 《算法题目解析系列》 的第 34 篇,本系列将持续更新,每篇都提供清晰的思路与编程语言实现。欢迎关注,第一时间获取更新。如果你有想看的题目,也可以在评论区留言告诉我。

相关推荐
Moshow郑锴40 分钟前
sql-pipeline - 基于PostgreSQL的SQL健康检查与发布编排平台
java·sql
weixin_307779134 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
海绵宝宝转agent7 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
小奇不哭7 小时前
ROS2 单节点,RGB-D 深度相机局部路径提取 + B 样条平滑路径 + YOLOv8 障碍物检测 + 深度测距,用于移动机器人视觉局部循迹。
python·yolov8·ros2·cv2·路径探索循迹
小小龙学IT8 小时前
Python scikit-learn 机器学习库深度解析
python·机器学习·scikit-learn
Wang's Blog8 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071578 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
hetao17338379 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
卷无止境9 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
\光辉岁月/9 小时前
5.java-数组
java·开发语言