代码随想录算法训练营第二十九天 | 回溯算法总结

代码随想录算法训练营第二十九天 | 回溯算法总结

1. 组合问题

1.1 组合问题

在77. 组合中,我们开始用回溯法解决第一道题目:组合问题。

回溯算法跟k层for循环同样是暴力解法,为什么用回溯呢?回溯法的魅力,用递归控制for循环嵌套的数量!

把回溯问题抽象为树形结构,如图:

在这里插入图片描述

可以直观的看出其搜索的过程:for循环横向遍历,递归纵向遍历,回溯不断调整结果集。

优化回溯算法只有剪枝一种方法,树形结构如图:

在这里插入图片描述

剪枝精髓是:for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够题目要求的k个元素了,就没有必要搜索了。

在for循环上做剪枝操作是回溯法剪枝的常见套路! 后面的题目还会经常用到。

1.2 组合总和

组合总和(一)

在216. 组合总和 III中,相当于在77. 组合加了一个元素总和的限制。

树形结构如图:

在这里插入图片描述

整体思路还是一样的,本题的剪枝会好想一些,即:已选元素总和如果已经大于n(题中要求的和)了,那么往后遍历就没有意义了,直接剪掉,如图:

在这里插入图片描述

在本题中,依然还可以有一个剪枝,就是77. 组合剪枝中提到的,对for循环选择的起始范围的剪枝。所以剪枝的代码可以在for循环加上 i <= 9 - (k - path.size()) + 1的限制!

组和总和(二)

在39. 组合总和中讲解的组合总和问题,和77.组合与216.组合总和III的区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。

本题还需要startIndex来控制for循环的起始位置,对于组合问题,什么时候需要startIndex呢?

如果是一个集合来求组合的话,就需要startIndex,例如:​77.组合与216.组合总和III
如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:17. 电话号码的字母组合
以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路。​

树形结构如下:

在这里插入图片描述
本题的剪枝优化,如下:

for (int i = idx; i < candidates.length; i++) {// 如果 sum + candidates[i] > target 就终止遍历if (sum + candidates[i] > target) break;

优化后树形结构如下:
在这里插入图片描述

组合总和(三)

在组合总和II中集合元素会有重复,但要求解集不能包含重复的组合。
所以难就难在去重问题上了。
为了讲解这个去重问题,科普两个概:“树枝去重”和“树层去重”。

“树枝去重”和“树层去重”出自代码随想录Carl

都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上“使用过”,一个维度是同一树层上“使用过”。没有理解这两个层面上的“使用过” 是造成大家没有彻底理解去重的根本原因。

在这里插入图片描述

我在图中将used的变化用橘黄色标注上,可以看出在candidates[i] == candidates[i - 1]相同的情况下:

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

对于去重,其实排列和子集问题也是一样的道理。

1.3 多个集合求组合

在17.电话号码的字母组合中,开始用多个集合来求组合,还是熟悉的模板题目,但是有一些细节。
例如这里for循环,可不像是在​77.组合与216.组合总和III中从startIndex开始遍历的。
因为本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,而​77.组合与216.组合总和III都是是求同一个集合中的组合!

树形结构如下:
在这里插入图片描述

1.4 切割问题

在131.分割回文串中,我们开始讲解切割问题,虽然最后代码看起来好像是一道模板题,但是从分析到学会套用这个模板,是比较难的。

以下是几个难点:

  • 切割问题其实类似组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 如何判断回文

如果想到了用求解组合问题的思路来解决切割问题本题就成功一大半了,接下来就可以对着模板照葫芦画瓢。
后续如何模拟切割线,如何终止,如何截取子串,其实都不好想,最后判断回文算是最简单的了。
除了这些难点,本题还有细节,例如:切割过的地方不能重复切割所以递归函数需要传入i + 1。

树形结构如下:
在这里插入图片描述

子集问题

子集问题(一)

在78. 子集中讲解了子集问题,在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果。

如图:
在这里插入图片描述

认清这个本质之后,今天的题目就是一道模板题了。

本题其实可以不需要加终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了,本来我们就要遍历整棵树。
不写终止条件会不会无限递归呢?
并不会,因为每次递归的下一层就是从i+1开始的。
如果要写终止条件,注意:result.add(new ArrayList<>(path));要放在终止条件的上面,如下:

result.add(new ArrayList<>(path));//「遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合」。if (startIndex >= nums.length){ //终止条件可不加return;}
子集问题(二)

在90.子集II中,开始针对子集问题进行去重。
本题就是78. 子集的基础上加上了去重,去重我们在组合总和II也讲过了,一样的套路。

树形结构如下:
在这里插入图片描述

递增子序列

在491.递增子序列中,处处都能看到子集的身影,但处处是陷阱,值得好好琢磨琢磨!

树形结构如下:
在这里插入图片描述
很多同学都会把这道题目和90.子集II混在一起。

2. 排列问题

排列问题(一)

46. 全排列又不一样了。

排列是有序的,也就是说 [1,2] 和 [2,1] 是两个集合,这和之前分析的子集以及组合所不同的地方。
可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。

如图:
在这里插入图片描述
大家此时可以感受出排列问题的不同:

  • 每层都是从0开始搜索而不是startIndex
  • 需要used数组记录path里都放了哪些元素了
排列问题(二)

排列问题也要去重了,在47. 全排列 II中又一次强调了“树层去重”和“树枝去重”。

树形结构如下:
在这里插入图片描述
这道题目神奇的地方就是used[i - 1] = = false也可以,used[i - 1] = = true也可以!

本题used数组即是记录path里都放了哪些元素,同时也用来去重,一举两得。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/117512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu tools

1 cloc calculate lines of your code sudo apt-get install cloccloc ./file

【MySQL架构篇】SQL执行流程与缓冲池

文章目录 1. SQL执行流程2. 数据库缓冲池(Buffer Pool)2.1 缓冲池概述2.2 缓冲池如何读取数据2.3 查看和设置缓冲池的大小2.4 多个Buffer Pool实例2.5 引申问题 1. SQL执行流程 查询缓存&#xff1a;因为查询效率往往不高&#xff0c;所以在MySQL8.0之后就抛弃了这个功能解析器…

lvs+keepalived: 高可用集群

lvskeepalived: 高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived软件。实现的是调度器的高可用。 但是&#xff1a;keepalived不是专门为集群服务的&#xff0c;也可以做其他服务器的高可用。 lvs的高可用集群&#xf…

力扣第1005题 K 次取反后最大化的数组和 c++ 贪心 双思维

题目 1005. K 次取反后最大化的数组和 简单 相关标签 贪心 数组 排序 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以…

asp.net乡村旅游管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net乡村旅游管理系统是一套完善的web设计管理系统系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c# 语言开发 asp.net乡村旅游管理系统 二、…

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】 1、概述2、实验环境3、 物品说明4、参考资料与自我总结5、实验过程1、创建目录2、克隆下载文件3、 拉取子目录安装和交叉编译工具链等其他工具4、添加环境变量6、将样例文件拷贝到桌面…

【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步

MySQL数据同步到Elasticsearch之N种方案解析&#xff0c;实现高效数据同步 前提介绍MySQL和ElasticSearch的同步双写优点缺点针对于缺点补充优化方案 MySQL和ElasticSearch的异步双写优点缺点 定时延时写入ElasticSearch数据库机制优点缺点 开源和成熟的数据迁移工具选型Logsta…

软考系列(系统架构师)- 2016年系统架构师软考案例分析考点

试题一 软件架构&#xff08;质量属性、架构风格对比、根据描述填空&#xff09; 试题二 系统开发&#xff08;用例图参与者、用例关系、类图关系&#xff09; 学生、教师、管理员、时间、打印机【问题2】&#xff08;7分&#xff09; 用例是对系统行为的动态描述&#xff0c;用…

ant框架下 a-input-number组件的宽度问题

如图所示&#xff0c;在使用a-input-number组件时虽然设置了宽度但是没有生效&#xff0c;加上了一个!important就好了&#xff1a;

【Java 进阶篇】使用 Java 和 Jsoup 进行 XML 处理

XML&#xff08;可扩展标记语言&#xff09;是一种常用的数据交换格式&#xff0c;它被广泛用于在不同系统之间传递和存储数据。Java作为一种强大的编程语言&#xff0c;提供了多种方式来处理XML数据。其中&#xff0c;Jsoup 是一个流行的Java库&#xff0c;用于解析和操作XML文…

Leetcode—2678.老人的数目【简单】

2023每日刷题&#xff08;八&#xff09; Leetcode—2678.老人的数目 int countSeniors(char ** details, int detailsSize){ int ans 0; int i; int tens 0; int ones 0; for(i 0; i < detailsSize; i) { tens ((details i) 11) - ‘0’; ones ((details i) 12)…

FOC系列(一)----DRV8301芯片的学习

一、 写在前面 从今年四五月份一直就想玩个无刷直流电机&#xff08;BLDC&#xff09;&#xff0c;但是碍于一直没时间。其实很早就做出来了测试板的控制板&#xff0c;可以当做开发板使用&#xff0c;考虑到成本问题&#xff0c;最后选用STM32F103CBT6芯片&#xff0c;下面是很…

Python爬虫网易云音乐,Tkinter制作音乐播放器

目录 一、效果展示 二、环境 三、实现过程 四、源码 一、效果展示 页面的美化以及功能还有待升级~ 先来说一下已有功能吧&#xff1a; 可以在搜索框中通过歌曲或歌手名称进行搜索&#xff0c;效果和在网易云官网搜索一样。 点击开始下载&#xff0c;就会将搜索结果的第一…

xshell+xming显示jmeter的gui页面

1.下载和安装xming&#xff0c;下载地址&#xff1a;https://sourceforge.net/projects/xming/ 2.配置xming 记住这个端口&#xff0c;一会要用到 修改进入xming安装目录修改host文件 此处是远程服务器的ip 3.服务器执行vi /etc/ssh/sshd_config&#xff0c;修改成如图所示…

Class类文件中的“咖啡宝贝”

Class文件是一组以8个字节为基础单位的二进制流&#xff0c;各个数据项目严格按照顺序紧凑地排列在文件之中&#xff0c;中间没有添加任何分隔符&#xff0c;整个Class文件中存储的内容几乎全部是程序运行的必要数据&#xff0c;没有空隙存在。 字节码&#xff08;Byte Code&am…

SpringAOP源码解析之advice构建排序(二)

上一章我们知道Spring开启AOP之后会注册AnnotationAwareAspectJAutoProxyCreator类的定义信息&#xff0c;所以在属性注入之后initializeBean的applyBeanPostProcessorsAfterInitialization方法执行的时候调用AnnotationAwareAspectJAutoProxyCreator父类(AbstractAutoProxyCre…

CDC实时数据同步

一丶CDC实时数据同步介绍 CDC实时数据同步指的是Change Data Capture&#xff08;数据变更捕获&#xff09;技术在数据同步过程中的应用。CDC技术允许在数据源发生变化时&#xff0c;实时地捕获这些变化&#xff0c;并将其应用到目标系统中&#xff0c;从而保持数据的同步性。…

电脑软件:推荐一款非常强大的pdf阅读编辑软件

目录 一、软件简介 二、功能介绍 1、界面美观&#xff0c;打开速度快 2、可直接编辑pdf 3、非常强大好用的注释功能 4、很好用的页面组织和提取功能 5、PDF转word效果非常棒 6、强大的OCR功能 三、软件特色 四、软件下载 pdf是日常办公非常常见的文档格式&#xff0c;…

手写 Promise(2)实例方法与静态方法的实现

一&#xff1a;什么是 Promise Promise 是异步编程的一种解决方案&#xff0c;其实是一个构造函数&#xff0c;自己身上有all、reject、resolve这几个方法&#xff0c;原型上有then、catch等方法。 Promise对象有以下两个特点。 &#xff08;1&#xff09;对象的状态不受…

大学兼职教师管理系统 用JAVA语言开发

一、项目介绍 基于VueSpringBootMySQL的大学兼职教师管理系统包含学生管理、教师管理、课程档案管理、课程评价管理、课程考勤管理、授课管理、课程成绩管理教龄/薪资分析可视化图表&#xff0c;还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管…