跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

DFS 算法详解:求解数组子集问题

子集生成问题通常使用深度优先搜索(DFS)结合回溯法解决。文章对比了两种决策树构建思路:一种是针对每个元素判断选或不选,另一种是按顺序选取元素并控制数量。核心在于维护当前路径 path 和结果集合 ret,通过递归遍历所有合法状态。文中详细解释了剪枝策略以避免重复子集,并给出了 C++ 实现的关键逻辑与代码结构,帮助理解子集问题的通用解法。

暗影行者发布于 2026/3/16更新于 2026/8/2244 浏览
DFS 算法详解:求解数组子集问题

示例图


1.上期参考代码

class Solution {
    vector<vector<int>> ret;
    vector<int> path;
    vector<bool> check = vector<bool>(6, false);
public:
    vector<vector<int>> permute(vector<int>& nums) {
        dfs(nums);
        return ret;
    }
    void dfs(vector<int>& nums) {
        if (path.size() == nums.size()) {
            ret.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            if (check[i] == false) {
                path.push_back(nums[i]);
                check[i] = true;
                dfs(nums);
                // 回溯
                check[i] = false;
                path.pop_back();
            }
        }
    }
};

2.本期知识点导图

文章配图

3.本期要讲解的题目是

子集

文章配图

要点:

  • nums 元素各异
  • 要返回空集

4.解题

本题我们可以画出两种决策树。

4.1 决策树 1

高中,我们学集合的时候知道,一个集合的子集个数为 2^n 个。这个 2^n 怎么来的?

在一个元素对于集合来说,只有两种情况:存在或者不存在。

对于每一个元素进行存在或者不存在的划分,我们可以得出以下的决策图:

文章配图

我们发现决策树的结果完全符合我们的期望,所以这就是一个好的决策树。

有了决策树,根据其写代码就方便多啦~

根据决策树,我们得出需要

两个全局变量:

  • 上一级已经存放了的元素–>变量path(也可以设置成函数参数,避免返回现场操作)
  • 存放 path 的二维数组用于返回所有结果–>ret
父子层信息传递需要:
  • 数组–>nums
  • 这一层是对数组中第几个元素进行判断–>pos
代码逻辑

观察我们想要的结果,都是在叶子结点,很明显,

出口在叶子节点

重复子问题:对于每个元素根据其是否存在,分两种情况讨论 子问题干啥:存在则将其放入 path 中,进入下一层,不存在啥也不做,进入下一层

4.2 决策树 2

我们也可以根据,子集中元素的个数,来画决策图:

文章配图

这张决策图同样需要全局变量 path 和 ret,它也能获得我们想要的结果,也是一个好的决策图。

由于子集中没有排序,只有组合,所以我们要对重复的子集进行剪枝,如图中所示:按照顺序来给 path 添加元素。

提示: 结合 for 循环,不用设置 return 出口,for 循环能实现数组递归中的按下标顺序添加元素,进行剪枝,出口的本质是:'没有可选择元素'。

不知道大家有没有发现,数组往往是多叉树的遍历,多叉树的遍历必然用到 for,而 for 往往是遍历到最后,也就不需要设置 return 出口~

5.下期要讲解的题目是:

找出所有子集的异或总和再求和

目录

  1. 1.上期参考代码
  2. 2.本期知识点导图
  3. 3.本期要讲解的题目是
  4. 子集
  5. 要点:
  6. 4.解题
  7. 4.1 决策树 1
  8. 父子层信息传递需要:
  9. 代码逻辑
  10. 4.2 决策树 2
  11. 5.下期要讲解的题目是:
  12. 找出所有子集的异或总和再求和
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 LLaMA-Factory 和 LoRA 在 AutoDL 上微调 GPT-OSS-20B 模型
  • HDFS 核心组件深度解析:分布式文件系统架构基石
  • Spring MVC 响应处理与设置方法
  • Circle Loss:统一 Softmax 与 Triplet 的优化视角
  • Happy Coder:Claude Code 的移动端与 Web 客户端
  • 116 道网络安全工程师面试真题及参考答案
  • OpenClaw 接入飞书机器人配置全流程
  • Wfuzz Web 应用模糊测试工具详解
  • 单链表综合练习:删除指定节点、反转链表与查找中间节点
  • LangChain Agent 核心概念与实战开发指南
  • 大模型工具调用演进:从 Function Calling 到 MCP
  • 3 种方法快速判断 Ubuntu 系统 ARM 或 x86 架构
  • 基于 Figma-MCP 与 Claude Code 实现 UI 设计稿 1:1 还原
  • 当养老遇上 AI 大模型:ATEC 2023 科技助老赛题解析
  • 为什么要学习模型和方法论
  • Java 面试基础:封装、继承与多态详解
  • OpenClaw 集成飞书机器人配置指南
  • Claude Skills 技术详解与实战指南
  • 马斯克与 OpenAI 的“混乱分手”内幕:人才争夺、AGI 与权力斗争
  • 2026最强外贸工具:Megick

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online