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

news2024/9/24 19:16:09

文章目录

  • 前言
  • 从N叉树说起
  • 为什么有的问题暴力搜索也不行
  • 总结


前言


提示:我对你透露一个大密码,这是人类最古老的玩笑。往哪走,都是往前走。 --米兰·昆德拉

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

回溯可以视为递归的拓展,很多思想和解法都和递归密切相关,再很多材料中都将回溯与递归(一同解释)

,后续我们会遇到路径问题,这就是很典型的问题(相结合的形式),学习回溯时,可以更好的理解递归,相反也是一样的。

关于递归和回溯,这里也区分一下,假设一个场景是这样的:我想脱单怎么办

  • 递归策略:先与意中人制造偶遇,然后了解人家的情况,然后约人家吃饭,有好感以后尝试拉手,如果没拒绝,就尝试表白啦。
  • 回溯策略:先统计周围所有的单身女孩,然后一个一个表白,被拒绝就说“我喝醉了”,然后就当什么事情也没发生,继续找下一个。

其实回溯的本质就是这么一个过程,好好想一下,看看有没有感觉~。

回溯最大的好处就是有非常明确的模板,所以这里的回溯都是有一个大框架,因此透彻理解回溯的框架是解决一切回溯问题的基础。所以这里做到是就是分析这个框架,让你彻底搞明白。

当然回溯并不是万能的,而且解决问题也是非常明确,例如:

  1. 组合
  2. 分割
  3. 子集
  4. 排序
  5. 棋盘

不过这些问题,在处理的时候具体措施也有不同,这里我们接着往下看。

回溯可以理解为递归的扩展,代码层面上又很像深度遍历的N叉树,因此只要知道递归,理解回溯并不难,难在很多人不理解为什么在递归之后会有个“撤销”的动作。这里通过图示给你解释清楚,这里假设一个场景,如果你这个时候谈新女朋友了,来你家之前,你时候会将你前任的东西藏起来?回溯就是这样,有些信息是前任的,需要处理掉,重新开始才行。

回溯最让人激动的是有非常清晰的解题模板,如下所示,大部分的回溯代码的框架都是这个样子,具体的我们后面在解释:

void backtracking(参数){
	if(终止条件){
		存放结果;
		return;
	}
	for(选择本层集中元素(画成树,就是树节点孩子的大小)){
		处理节点;
		backtracking();
		回溯,撤销处理结果;
	}
}

回溯是有明确的解题模板,下面我们就具体分析一下。

从N叉树说起

解释之前,还是看看N叉树的遍历吧,我们知道二叉树的前序过程:

void treeDFS(TreeNode root) {
	if(root == null){
		return;
	}
	system.out.println(root.val);
	treeDFS(root.left);
	treeDFS(root.right);
}

class TreeNode{
	int val;
	TreeNode left;
	TreeNode right;
}

这里如果是三叉树,四叉树甚至N叉树该怎么处理呢?很显然这里不能用left和right来表示分支了,使用一个List比较好,也就是下面这个例子:

class TreeNode{
	int val;
	List<TreeNode> nodes;
}

代码就需要改一下了:

public statis void treeDFS(TreeNode root) {
	// 递归的必要终止条件
	if(root == null){
		return;
	}
	// 处理节点
	system.out.println(root.val);
	// 通过循环,分别遍历N个字数
	for(int i = 1; i <= node.length; i++){
		treeDFS("第i个字节点");
	}
}

到这里,你有没有发现已经很相似了,说明两者之间确实存在某种必要的联系。其他的咱们暂时不管,我们是否已经记住刚才的那个框架了。(N叉树的遍历)

为什么有的问题暴力搜索也不行

试想一下,回溯主要解决暴力枚举处理不了的问题,为什么这么神奇,暴力解决不了?

参考题目介绍:77. 组合 - 力扣(LeetCode)

在这里插入图片描述

这里说先明确一点:如果n=4,k=2.那就是说从4个数种选择2个,问你最后能选出多少组数据。

这里类似高中的一个数学题:大致说一下过程,如果数字n=4,能用的数字就是{1,2,3,4}

  1. 先取出一个1,则有[1,2]、[1,3]、[1,4]三种可能。
  2. 再取出一个2,1已经取过了,不能再取了,则可以取[2,3]、[2,4]两种可能。
  3. 再取一个3,1和2都已经取过了,不能再取了,这里就剩下[3,4]一种可能了。
  4. 取4,以为1,2,3都已经取过了,所以就直接返回null。
  5. 最后的结果就是[1,2]、[1,3]、[1,4、[2,3]、[2,4]、[3,4]

这里我们思考下该问题要怎么实现,假如只有两个数,采用双层循环就可以了:

int n = 4;
for(int i = 1; i <= n; i++){
	for(int j = i + 1; j <= n; j++){
		system.out.println(i + " "+j);
	}
}

那如果n和k都变大,比如说n=200,k是3呢?也可以采用三层循环搞定:

int n = 200;
for(int i = 1; i <= n; i++){
	for(int j = i + 1; j <= n; j++){
		for(int l = j + 1; l <= n; l++){
			system.out.println(i + " "+j +" " + l);
		}
	}
}

如果这里的k是5呢?如果更大呢?这里就不好写了吧?甚至告诉你k就是一个未知的正整数k,你需要怎么写循环呀,是不是无解了,这里已经无能为力的吧,这里就是说暴力搜素不能解决。

这就是组合类型问题,除此以外子集、排序、切割、棋盘等方面都有类似的问题,我们可以好好学习一下。


总结

提示:回溯算法;初始回溯;什么叫回溯;回溯的套路;回溯的核心问题


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

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

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

在这里插入图片描述

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

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

相关文章

第五章 I/O管理 五、输入/输出应用程序接口设备驱动程序接口

目录 一、应用程序接口 二、阻塞和非阻塞I/O 阻塞I/O: 非阻塞I/O: 三、设备驱动程序 一、应用程序接口 以前的统一接口不适用了&#xff0c;现在改为了几种不同的接口 二、阻塞和非阻塞I/O 阻塞I/O: 应用程序发出I/O系统调用&#xff0c;进程需转为阻塞态等待。 eg:字符…

40 深度学习(四):卷积神经网络|深度可分离卷积|colab和kaggle的基础使用

文章目录 卷积神经网络为什么要卷积卷积的具体流程池化tensorflow代码 深度可分离卷积原理介绍计算量对比代码参数计算例子 colab 和 kagglecolabkaggle如何在colab上使用kaggle的数据 卷积神经网络 卷积神经网络的基本结构 1&#xff1a; (卷积层(可选)池化层) * N全连接层 *…

保险公司【Hamilton Insurance】申请1亿美元纽交所IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于美国的保险公司Hamilton Insurance Group, Ltd&#xff08;简称&#xff1a;Hamilton Insurance&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff…

力扣每日一题86:分隔链表

题目描述&#xff1a; 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,…

陷阱,实时IO判断避坑!

这是题面&#xff1a; 然后我写了如下代码: #include<iostream> #include<map> #include<vector> #include<algorithm> using namespace std; #define int long long int const int maxLine50010; map<char,char> mymap; int arr[maxLine]{1,2…

数据结构Demo——简单计算器

简单计算器 一、项目介绍二、技术使用三、具体代码实现1.前端部分2.后端部分 一、项目介绍 本项目实现了一个通过网页访问的简单计算器&#xff0c;它可以对带括号的加减乘除表达式进行计算并将计算结果返回给用户&#xff0c;并且可以对用户输入的表达式进行合法性判断&#…

SV-10A-4G IP网络报警非可视终端 (4G版)

SV-10A-4G IP网络报警非可视终端 &#xff08;4G版&#xff09; https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.621e3d0dpv5knb&ftt&id745728046948 产品简介&#xff1a; 通过局域网/广域网网组网的网络报警系统&#xff0c;改变传统局域网组网…

【MySql】10- 实践篇(八)

文章目录 1. 用动态的观点看加锁1.1 不等号条件里的等值查询1.2 等值查询的过程1.3 怎么看死锁&#xff1f;1.4 怎么看锁等待&#xff1f;1.5 update 的例子 2. 误删数据后怎么办?2.1 删除行2.2 误删库/表2.3 延迟复制备库2.4 预防误删库 / 表的方法2.4.1 账号分离2.4.2 制定操…

人工智能(8):Numpy的使用

1 Numpy介绍 Numpy&#xff08;Numerical Python&#xff09;是一个开源的Python科学计算库&#xff0c;用于快速处理任意维度的数组。 Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务&#xff0c;使用Numpy比直接使用Python要简洁的多。 Numpy使用ndarray对象来处理…

NSGA-II 遗传多目标算法(python示例)

一、前言 最近在准备毕业论文&#xff0c;研究了一下主流的多目标算法&#xff0c;对于NSGA-II&#xff0c;网上大部分代码是全部是面向过程来实现的&#xff0c;本人更喜欢采用面向对象的方式&#xff0c;故采用python面向对象实现了一个示例&#xff0c;实现了对于二元多目标…

1400*C. Element Extermination(贪心规律)

Problem - 1375C - Codeforces 解析&#xff1a; 可以发现&#xff0c;最左端的数字&#xff0c;无论删除自己还是下一个&#xff0c;这个位置的值都不会变小。 同理&#xff0c;最右端位置的值都不会变大。 所以当最后剩余两个数字的时候&#xff0c;只有左端小于右端数字&…

STM32—PWM开发SG90舵机

目录 PWM介绍 PWM输出模式&#xff1a; ​编辑PWM占空比&#xff1a; PWM周期与频率公式&#xff1a;​编辑 SG90舵机介绍 1. 什么是舵机 2. 怎么控制舵机 SG90舵机介绍实战 1. 在 SYS 选项里&#xff0c;将 Debug 设为 Serial Wire​编辑 2. 将 RCC 里的 HSE 设置为 …

Vue的快速入门

Vue的快速入门 下载并安装vue.js Vue是一个基于JavaScript实现的框架, 要使用它就需要从[Vue官网]((https://cn.vuejs.org/)下载 vue.js 文件 第一步&#xff1a;打开Vue2官网&#xff0c;点击下图所示的“起步” 第二步&#xff1a;继续点击下图所示的“安装” 第三步&…

二叉树的遍历+二叉树的基本操作

文章目录 二叉树的操作一、 二叉树的存储1.二叉树的存储结构 二、 二叉树的基本操作1.前置创建一棵二叉树&#xff1a;1. 定义结点 2.简单的创建二叉树 2.二叉数的遍历1.前序遍历2.中序遍历3.后序遍历4.层序遍历 3.二叉树的操作1.获取树中节点的个数2.获取叶子节点的个数3.获取…

PHP的Excel导出与导入

下载地址&#xff08;注意php版本大于7.3可能会报错&#xff09; GitHub - PHPOffice/PHPExcel: ARCHIVED 解压 1、导出 Excel $data[[name>a,age>11],[name>b,age>22],[name>d,age>33], ]; $fileds["name">"名称","age"…

在Java和PostgreSQL枚举之间进行转换的通用方法

枚举类型&#xff08;enum&#xff09;是一种方便的数据类型&#xff0c;允许我们指定一个常量列表&#xff0c;对象字段或数据库列可以设置为该列表中的值。 枚举的美妙之处在于我们可以通过提供人类可读格式的枚举常量来确保数据完整性。因此&#xff0c;Java和PostgreSQL原…

MySQL 8.2 支持读写分离!

我们一直在等待的 MySQL 读/写分离功能 现在终于可以使用了&#xff01; 在规模上&#xff0c;我们在副本之间分配读取&#xff0c;但这必须在应用程序中以某种方式进行管理&#xff1a;指向在某个地方写入并在其他地方读取。 在 MySQL 8.2 中&#xff0c;MySQL Router 现在能…

SSH 无密登录设置

1 &#xff09; 配置 ssh &#xff08;1&#xff09;基本语法 ssh 另一台电脑的 IP 地址&#xff08;2&#xff09;ssh 连接时出现 Host key verification failed 的解决方法 [libaihadoop102 ~]$ ssh hadoop103 ➢ 如果出现如下内容 Are you sure you want to continue c…

设计模式(20)职责链模式

一、介绍&#xff1a; 1、定义&#xff1a;责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链&#xff0c;并沿着…

SpringSecurity6从入门到上天系列第二篇:搭建SpringSecurity6的入门级别程序!

文章目录 前言 1&#xff1a;环境要求 2&#xff1a;技术要求 一&#xff1a;搭建SpringBoot环境 1&#xff1a;创建空项目 2&#xff1a;创建SpringBoot项目 3&#xff1a;编写一个简单的controller 二&#xff1a;整合SpringSecurity 1&#xff1a;引入依赖 2&…