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

算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)

文章目录

  • 前言
  • 回溯的核心问题
  • 撤销操作解释
  • 总结


前言


提示:阳光好的时候,会感觉还可以活很久,甚至可以活出喜悦。 --余秀华

回溯是非常重要的算法思想之一,主要解决一些暴力枚举也搞不定的问题(这里埋个坑💣)例如组合、分割、子集、棋盘等等。从性能角度来看回溯算法的效率并不是很高,但是对于暴力也解决不了的问题,它往往很快可以出结果,效率低就可以理解了吧。接下来,就看看回溯的事情吧🤩

回溯的核心问题

递归+局部枚举+放下前任

接着看这个题目:77. 组合 - 力扣(LeetCode)


当n = 4时,我们可以选择的有n有{1,2,3,4}这四种情况,所以我们从第一层到第二层的分支有四个,分别表示可取1,2,3,4.而且这里从左到右取数,取过的数,不在重复取。第一次取1,集合变为2,3,4.因为k= 2,我们也只能再取1个数就可以了,分别取2,3,4.得到的集合就是[1,2]、[1,3]、[1,4]。一次类推:

横向:

在这里插入图片描述
每次从集合中选取元素,可选择的范围回逐步收缩,到了取4时就直接返为空了。

继续观察树结构,可以发现,图中每次访问到一个叶子节点(图中的标记处),我们就可以得到一个结果。虽然到最后时空的,但是不影响最终结果。这里相当于从根节点开始每次选择的内容(分支)达到叶子节点时,将其收起起来就是我们想要的结果。

你可以尝试画下n=5,k=3的结果:有没有感觉

在这里插入图片描述
从图中我们发现元素个数n相当于树的宽度(横向),而每个结果的元素个数k相当于树的深度(纵向)。所以我们说回溯问题就是一纵一横而已。在分析我们回发现下面几个规律:

  • 我们每次选择都是从类似{1,2,3,4},{1,2,3,4}这个样的序列中一个一个选的,这就是为什么说是局部枚举,后面的枚举范围回越来越小。
  • 枚举时,我们就是简单的暴露测试而已,一个一个验证,能否满足要求,从上图可以看到,这就是N叉树的遍历过程,一次代码相似度很高。
  • 我们再看叶子过程,这部分是不是和(n = 4,k = 2)处理的结果一致,也就说是很明显的递归结构。

到此,我们还有一个问题待解决,就是回溯一般会有一个手动撤销的操作,为什么要这么做呢?

继续观察纵横图:
在这里插入图片描述
我们可以看到,我们收集的每个结果不是针对叶子节点的,而是针对树枝的,比如最上层我们首先确定了1,下层我们如果选择了2,那么结果就是{1,2},如果选择了3,结果就是{1,3}.一次类推。现在时怎么确定得到第一个结果时{1,2}之后,得到第二个结果是{1,3}呢?

继续观察纵横图 ,可以看到,我们在得到{1,2}之后将2撤销,再继续使用3,就得到了{1,3},同理也可以得到{1,4},之后这一层就没有了,我们可以撤销1,继续从最上层取2继续进行。

这里对应的代码操作就是先将第一个结果放在临时列表的Path里面,得到第一个结果{1,2},之后就将path里面的内容放进结果列表resultList中,之后,将path里面的2撤销掉,继续寻找下一个结果{1,3},继续将path加入resultList中,然后再次撤销,继续寻找。

现在了解为什么要撤销,看图。这个过程,我们称它“放下前任,继续前进”,后面的回溯大都是这样的思路。

这几条就是回溯的基本规律,了解这一点,我们就可以看看代码是怎么回事了,到此我们看看完整的代码时怎样的:

 public List<List<Integer>> combine(int n, int k) {List<List<Integer>> res = new ArrayList<>();if (k <=0 || n < k){return res;}Deque<Integer> path = new ArrayDeque<>();dfs(n,k,1,path,res);return res;}public void dfs(int n,int k,int startIndex,Deque<Integer> path,List<List<Integer>> res){// 递归终止条件,path 等于k(刚好完成一次if (path.size() == k){res.add((new ArrayList<>(path)));return;}// 针对每个节点,这里就是遍历搜索,也就是枚举for(int i = startIndex; i <= n; i++){// 向路径里添加一个数(分支里的取值path.addLast(i);// 搜索起点要加1,就是缩小范围,准备下一轮递归(这里不允许重复dfs(n,k,i + 1,path,res);// 递归之后要做同样的逆向操作,撤销掉path.removeLast();}}

上面代码还有一个问题需要解释:startIndex和i是怎么变化的,为什么要传递到下一层(+ 1)

我们来看看这里的递归循环:

   // 针对每个节点,这里就是遍历搜索,也就是枚举for(int i = startIndex; i <= n; i++){// 向路径里添加一个数(分支里的取值path.addLast(i);// 搜索起点要加1,就是缩小范围,准备下一轮递归(这里不允许重复dfs(n,k,i + 1,path,res);// 递归之后要做同样的逆向操作,撤销掉path.removeLast();}

这里的循环有什么作用呢?看看这里,其实来说是一个枚举,第一次n=4,可以选择1,2,3,4四种情况,所以就存在4个分支,for就需要执行4次:
在这里插入图片描述
对于第二层来说,第一个数,选择1之后,身下的元素就只有2,3,4了。所以这时候for循环就执行3次,后面的只有2次和1次了。

撤销操作解释

如果你还是不清楚的话,这里就带图详细的走一遍,回溯也就是这个地方有点晕,拿下就是胜利✌。

   // 针对每个节点,这里就是遍历搜索,也就是枚举for(int i = startIndex; i <= n; i++){// 向路径里添加一个数(分支里的取值path.addLast(i);// 搜索起点要加1,就是缩小范围,准备下一轮递归(这里不允许重复dfs(n,k,i + 1,path,res);// 递归之后要做同样的逆向操作,撤销掉path.removeLast();}

为什么要remove呢?看下图,当第一层取1时,最底层的遍历从左到右执行,取2,取3,取4.而取3的时候,此时res里面存储的是{1,2},所以这里前提是需要撤销掉2(path.removeLast();)的作用。

这里我们拆解一下递归方法,将递归拆分成函数调用,输出第一条路径{1,2}的步骤如下:
在这里插入图片描述
我们在递归说过一个特点:不到南墙不回头,回溯也是这个道理,我们看看这个过程。

在这里插入图片描述
然后,怎么在次进行呢,这里就需要撤回一下了,但是如果将这里的remove代码去掉,就会是这个样子:
在这里插入图片描述
这里知道遍历完成,然会的就不做撤销,就会下一场进入for循环,也就是回变成{1,2,3}.

path是一个全局的引用的,各个递归的函数是公用的,所以这里处理完{1,2},之后,需要把2撤出去,将1保留,再让三进入,从而得到{1,3}.所以这里不许remove一下的。

同样处理完之后,后续的也是依次处理,需要撤销的,这里也就是不得不处理撤销的操作。


总结

提示:什么叫回溯;保留状态;撤销操作;回溯核心思想;回溯的入门


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。

在这里插入图片描述

相关文章:

算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)

文章目录 前言回溯的核心问题撤销操作解释总结 前言 提示&#xff1a;阳光好的时候&#xff0c;会感觉还可以活很久&#xff0c;甚至可以活出喜悦。 --余秀华 回溯是非常重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff08;这里埋个坑&#x1f4a3;…...

generate by chatgpt:应用上线前的checkList(部分是我自己的回答)

prompt 1 想象你是一名高级测试工程师&#xff0c;在应用上线前你需要提供一份checklist,请写出来: 作为一名高级测试工程师&#xff0c;以下是我在应用上线前的检查清单&#xff1a; 功能性测试&#xff1a; 检查所有要素和功能是否正常工作。确保满足了所有用户故事/需求。…...

Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…...

基于信号功率谱特征和GRNN广义回归神经网络的信号调制类型识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ................................................................ %调制识别 len1 func_f…...

matplotlib从起点出发(10)_Tutorial_10_Layout

使用受约束的绘图干净整洁地将图形合适排列。 受约束的布局会自动调整子图&#xff0c;以便刻度标签、图例和颜色条等装饰不会重叠&#xff0c;同时仍保留用户请求的逻辑布局。 受约束布局类似于“紧密布局”&#xff0c;但它要更灵活。它处理放置在多个轴上的Axes(放置颜色条…...

HTTP头部信息解释分析(详细整理)(转载)

这篇文章为大家介绍了HTTP头部信息&#xff0c;中英文对比分析&#xff0c;还是比较全面的&#xff0c;若大家在使用过程中遇到不了解的&#xff0c;可以适当参考下 HTTP 头部解释 1. Accept&#xff1a; 告诉WEB服务器自己接受什么介质类型&#xff0c;/ 表示任何类型&#…...

集线器、交换机、网桥、路由器、网关

目录 集线器(HUB)交换机(SWITCH)网桥(BRIDGE)路由器(ROUTER)网关(GATEWAY)交换机和路由器的区别参考 集线器(HUB) 功能 集线器对数据的传输起到同步、放大和整形的作用 属于物理层设备 工作机制 使用集线器互连而成的以太网被称为共享式以太网。当某个主机要给另一个主机发送单…...

项目实战:新增@Controller和@Service@Repository@Autowire四个注解

1、Controller package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Inherited public interface Controller { }2、Service package com.csdn.mymvc.annotation; import java.lang.annotation.*…...

校验 ChatGPT 4.0 真实性的三个经典问题:快速区分 GPT3.5 与 GPT4,并提供免费测试网站

现在已经有很多 ChatGPT 的套壳网站&#xff0c;以下分享验明 GPT-4 真身的三个经典问题&#xff0c;帮助你快速区分套壳网站背后到底用的是 GPT-3.5 还是 GPT-4。 大家可以在这个网站测试&#xff1a;https://ai.hxkj.vip&#xff0c;免登录可以问三条&#xff0c;登录之后无限…...

Jetpack:030-Jetpack中的状态

文章目录 1. 概念介绍2. 使用方法2.1 可监听对象2.2 获取状态值2.3 修改状态值2.4 重组函数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack中网格布局相关的内容&#xff0c;本章回中主要 介绍状态。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧&#xff0…...

AD教程 (七)元件的放置

AD教程 &#xff08;七&#xff09;元件的放置 第一种放置方法 点击右下角Panels&#xff0c;选择SCH Library&#xff0c;调出原理图库器件列表选中想要放置的元件&#xff0c;点击放置&#xff0c;就会自动跳转到原理图&#xff0c;然后放置即可这种方法需要不断打开元件库…...

ubuntu22.04为什么鼠标会自动丢失焦点

排查的步骤 在Ubuntu 22.04中&#xff0c;鼠标自动丢失焦点可能由多种原因引起&#xff0c;包括系统错误、驱动问题、软件冲突或者某些特定的系统设置。以下是一些可能的原因和相应的解决方法&#xff1a; 触控板干扰&#xff1a; 如果你使用的是笔记本电脑&#xff0c;触控板可…...

FastBond2阶段2——基于ESP32C3开发的简易IO调试设备

1. 项目介绍 之前买了许多国产单片机esp32c3一直在吃灰&#xff0c;没有发挥它的真实价值。非常感谢硬禾组织的Fastbond2活动&#xff0c;刚好两者经过微妙的碰撞。恰可以用于FastBond2活动主题4 - 测量仪器&#xff08;单片机开发测试领域&#xff09;&#xff0c;或者用于国…...

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表

目录 Native 下单1、创建课程订单保存到数据库1-1&#xff1a;需求&#xff1a;1-2&#xff1a;代码&#xff1a;1-3&#xff1a;测试结果&#xff1a; 2、保存支付二维码的url2-1&#xff1a;需求&#xff1a;2-2&#xff1a;代码&#xff1a;2-3&#xff1a;测试&#xff1a;…...

【echarts基础】在柱形图上设置文本

一、需求描述 在柱状图上设置文本标签&#xff0c;按需修改它的颜色、大小、边框、阴影等&#xff0c;如下。 二、代码展示 series:[{name:"螺蛳粉",type:"bar",data:data.data.chartData.chartData.num.螺蛳粉,label:{//图形上显示文本标签formatter:&q…...

小户型工业风,陌生上开花知书香。福州中宅装饰,福州装修

漫步陌上 只因陌上花开 花是自然的那种 朴素而恬淡&#xff0c;不落尘俗。—徐志摩 小户型工业风格 满足业主需求 筑造书香押韵家 从动线、色彩、选材、定制等各个环节 与业主一起畅谈家的构造 形成别“居”一格的温暖品质家 以书做墙 告别电视墙 这是一个实用性很强的…...

Gorm 中的迁移指南

探索使用 GORM 在 Go 中进行数据库迁移和模式更改的世界 在应用程序开发的不断变化的景观中&#xff0c;数据库模式更改是不可避免的。GORM&#xff0c;强大的 Go 对象关系映射库&#xff0c;通过迁移提供了一种无缝的解决方案来管理这些变化。本文将作为您全面的指南&#xf…...

基于.NET、Uni-App开发支持多平台的小程序商城系统 - CoreShop

前言 小程序商城系统是当前备受追捧的开发领域&#xff0c;它可以为用户提供一个更加便捷、流畅、直观的购物体验&#xff0c;无需下载和安装&#xff0c;随时随地轻松使用。今天给大家推荐一个基于.NET、Uni-App开发支持多平台的小程序商城系统&#xff08;该商城系统完整开源…...

[python] 在多线程中将`logging.info`输出到不同的文件中 (生产者消费者)

在多线程中将logging.info输出到不同的文件中&#xff0c;可以使用Python标准库中的Queue和Thread模块。具体实现步骤如下&#xff1a; 创建多个Queue队列用于不同线程的日志输出&#xff0c;每个队列对应一个日志文件。 import queue# 创建三个队列用于不同线程的日志输出 l…...

MySQL进阶_5.逻辑架构和SQL执行流程

文章目录 第一节、逻辑架构剖析1.1、服务器处理客户端请求1.2、Connectors1.3、第1层&#xff1a;连接层1.4、第2层&#xff1a;服务层1.5、 第3层&#xff1a;引擎层1.6、 存储层1.7、小结 第二节、SQL执行流程2.1、查询缓存2.2、解析器2.3、优化器2.4、执行器 第三节、数据库…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

【QT控件】显示类控件

目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏&#xff1a;QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...

【Qt】控件 QWidget

控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态&#xff1a;enabled几何&#xff1a;geometrywindows frame 窗口框架的影响 窗口标题&#xff1a;windowTitle窗口图标&#xff1a;windowIconqrc 机制 窗口不透明度&#xff1a;windowOpacity光标&#xff1a;cursor…...