当前位置: 首页 > news >正文

回溯算法|78.子集

力扣题目链接

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉自己if (startIndex >= nums.size()) { // 终止条件可以不加return;}for (int i = startIndex; i < nums.size(); i++) {path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}
public:vector<vector<int>> subsets(vector<int>& nums) {result.clear();path.clear();backtracking(nums, 0);return result;}
};

这题比较好理解啦~

思路

求子集问题和77.组合 (opens new window)和131.分割回文串 (opens new window)又不一样了。

如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!

其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。

那么既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!

有同学问了,什么时候for可以从0开始呢?

求排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合,排列问题我们后续的文章就会讲到的。

以示例中nums = [1,2,3]为例把求子集抽象为树型结构,如下:

78.子集

从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合

#回溯三部曲

  • 递归函数参数

全局变量数组path为子集收集元素,二维数组result存放子集组合。(也可以放到递归函数参数里)

递归函数参数在上面讲到了,需要startIndex。

代码如下:

vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex) {

递归终止条件

从图中可以看出:

78.子集

剩余集合为空的时候,就是叶子节点。

那么什么时候剩余集合为空呢?

就是startIndex已经大于数组的长度了,就终止了,因为没有元素可取了,代码如下:

if (startIndex >= nums.size()) {return;
}

其实可以不需要加终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了

  • 单层搜索逻辑

求取子集问题,不需要任何剪枝!因为子集就是要遍历整棵树

那么单层递归逻辑代码如下:

for (int i = startIndex; i < nums.size(); i++) {path.push_back(nums[i]);    // 子集收集元素backtracking(nums, i + 1);  // 注意从i+1开始,元素不重复取path.pop_back();            // 回溯
}

根据关于回溯算法,你该了解这些! (opens new window)给出的回溯算法模板:

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

自己的思路: 

其实我不太清楚空集它是如何保存的。

result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉自己

是这个吗?好像不是

好像也是的,一开始没有路径,直接push进去的就是空集

后面的就和之前几天写的代码差不多了,好理解~

 

相关文章:

  • 前端开发语言概览
  • 如何使用Python进行文件读写操作?
  • 深入解析大数据Scala面试题及参考答案(持续更新)
  • 谷粒商城实战(008 缓存)
  • 一维卷积神经网络的特征可视化
  • MySQL日志探索——redo log和bin log的刷盘时机详解
  • 实景三维:城市数据要素的新维度
  • YOLOv2
  • C++核心高级编程 --- 3、函数提高
  • 2024年阿里云服务器2核8G、4核16G、8核32G配置收费标准
  • Spring使用(一)注解
  • 梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码
  • qT 地图显示飞机轨迹
  • C语言_第一轮笔记_指针
  • 数据仓库——事实表
  • 0基础学习移动端适配
  • 77. Combinations
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Centos6.8 使用rpm安装mysql5.7
  • HomeBrew常规使用教程
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Java的Interrupt与线程中断
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 基于Android乐音识别(2)
  • 技术:超级实用的电脑小技巧
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 终端用户监控:真实用户监控还是模拟监控?
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Spring第一个helloWorld
  • 我们雇佣了一只大猴子...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • !!Dom4j 学习笔记
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (12)Hive调优——count distinct去重优化
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (二)c52学习之旅-简单了解单片机
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (三) diretfbrc详解
  • (十三)Maven插件解析运行机制
  • (转载)OpenStack Hacker养成指南
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .gitignore文件_Git:.gitignore
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET Core 项目指定SDK版本
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .netcore如何运行环境安装到Linux服务器
  • ::before和::after 常见的用法
  • :=
  • [1] 平面(Plane)图形的生成算法