对回溯的理解与思考(从决策树遍历角度分析)

news2024/10/2 8:44:09

对于回溯的经典问题,就是全排列和各种各样全排列的变体和八皇后问题。

算法框架

对于回溯算法框架。其实解决一个回溯问题,实际上就是一个决策树的遍历过程。

这也就是为什么在刷算法题之前,一定要从树的题目开始刷,后期可以很方便的树立使用递归求解问题的思路。

一般需要你明确三个元素:

  1. 路径: 当前已经做出的选择是哪些
  2. 选择列表:也就是你可以做出的选择
  3. 结束条件:到达树的底部,没有办法在做出的选择。

对于这三个概念,在后面的分析中,会反复的进行提及。
代码方面:

result = [] 
int[] path = new int[n]; // 路径
boolean[] st = new boolean[n]; // 是否被使用过
void dfs(当前遍历的位置){
	if(满足结束条件){
		result.add(路径);
		return;
	}
	for(int i = 0; i < 元素个数; i++){
		if(没有被使用过){
			做选择
			dfs(当前遍历的位置 + 1)
			撤销选择
		}
	}
}

其核心就是 for 循环里面的递归,回溯是一种特殊的DFS算法,在递归调用之前「做选择」,在递归调用之后「撤销选择」。

下面我们来分析一下全排列的问题,深化上面的概念:
什么是全排列问题,这边不在进行介绍,为了简化问题的概念,直接讨论的全排列问题不包含重复的数字

如果没有计算机,我们自己该如何做一个集合的全排列呢?一般对于[1,2,3]问题:
先固定第一位为 1,然后第二位可以是 2,那么第三位只能是 3;然后可以把第二位变成 3,第三位就只能是 2 了;然后就只能变化第一位,变成 2,然后再穷举后两位

算法其实也可以这样求解,
在这里插入图片描述
对于一些不满足条件题目条件的点,都进行删除,最后得到下面这颗树。
在这里插入图片描述
很明显,这其实就是一个多叉树的问题。而且对于树上的每一个节点都需要进行判断,才能继续下一步

为什么这样说?应为我们要求的是全排列的问题,对于图中红圈的点,之后的所有路径的选择都是需要排除掉1的。所以,对于每一个node,都需要进行判断。
在这里插入图片描述

按照上述的说明不满足条件题目条件的点,我们再来看一下具体是怎么操作的,为了更好的理解,我们把上述做决策的过程完全打开。

void dfs(node){
	// 1. 结束条件和存储结果 
	//2. 对于不符合结束条件的节点,我们应该对每一个节点都判断一下,形式如下
	if(node1 符合题目条件) {
		node(1) 访问node1, 递归操作
	}
	if(node2 符合题目条件) {
		node(2) 访问node2, 递归操作
	}
	if(node3 符合题目条件) {
		node(3) 访问node1, 递归操作
	}
	.....
}

那么也就是说明,当前层的满足条件的节点就会被记录下来,按照多叉树的遍历形式,里面呈现的就是一个for循环的格式。

但是,还有一个问题就是,一个决策树在同层直接涉及到的数据污染问题怎么解决。

比如:从袋子里面摸球问题,第一次你摸了1,如果从头开始摸球的话,需要把1号球给放入,然后摸出2号球。

如下图所示:
在这里插入图片描述
所以,我们需在在选择节点之后,对当前节点进行撤销选择才行,所以上述代码变为

void dfs(node){
	// 1. 结束条件和存储结果 
	//2. 对于不符合结束条件的节点,我们应该对每一个节点都判断一下,形式如下
	if(node1 符合题目条件) {
		// 标识已经对当前节点的访问
		标识节点做了选择
		node(1) 访问node1, 递归操作
		取消当前节点,设为没有选择状态
	}
	if(node2 符合题目条件) {
		标识节点做了选择
		node(2) 访问node2, 递归操作
		取消当前节点,设为没有选择状态
	}
	if(node3 符合题目条件) {
		标识节点做了选择
		node(3) 访问node1, 递归操作
		取消当前节点,设为没有选择状态
	}
	.....
}

也就是说,对于当前决策树中的所有节点,
在这里插入图片描述
对于递归的板子,里面的for循环就是横向移动,而对于for循环中的递归就是纵向移动,不断的深入到底部的过程。
让我们来看看全排列的代码:

import java.util.*;
import java.io.*;

class Main{
    static int N = 10;
    static int[] path = new int[N]; // 用来记录当前的路径 
    static boolean[] sta = new boolean[N]; //用来记录当前已经填了哪些数字
    // u代表当前已经填到了哪位
    public static void dfs(int u, int n){
        if(u == n){
            for(int i = 0; i < n; i ++) System.out.print(path[i] + " ");
            System.out.println();
            return;
        }
        // 对所有节点都看一下,如果符合条件的自然会拿出来
        for(int i = 1; i <= n; i ++){
            // 先判断当前数字是否已经被使用过
            if(!sta[i]){
                path[u] = i;
                sta[i] = true;
                dfs(u + 1, n);
                // 恢复现场
                sta[i] = false;
            }
        }
    }
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        dfs(0, n);
    }
}

总结

回溯算法就是个多叉树的遍历问题,关键就是在前序遍历和后序遍历的位置

某种程度上说,动态规划的暴力求解阶段就是回溯算法。只是有的问题具有重叠子问题性质,可以用dp table或者备忘录优化,将递归树大幅剪枝,这就变成了动态规划。而今天的两个问题,都没有重叠子问题,也就是回溯算法问题了,复杂度非常高是不可避免的。

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

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

相关文章

检索 COM 类工厂中 CLSID 为 {} 的组件失败, 内存资源不足,无法处理此命令

如果您收到ERROR_NOT_ENOUGH_MEMORY消息&#xff0c;提示没有足够的存储空间来处理此命令描述&#xff0c;请按照本文中列出的故障排除步骤进行修复。 此错误代码影响Windows服务器&#xff0c;导致系统崩溃&#xff0c;并在错误日志中显示“没有足够的存储空间来处理此命令”。…

Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/130762721 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

Clickhouse 入门到精通-Clickhouse工作原理

Clickhouse 为什么做查询分析那么快&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 因为clickhouse使用了下列方案&#xff1a; clickhouse 数据分区clickhouse 列式存储clickhouse 一级索引&#xff08;主键索引&#…

企业数字转型加速器!居然是他!该不会还有人没用上吧?

随着数字化时代的到来和技术的发展&#xff0c;企业数字化转型已经成为全球企业发展的重要趋势。然而&#xff0c;数字化转型的过程却并非一帆风顺&#xff0c;常常因为 IT 复杂度高、开发周期长等问题而遇到许多挑战&#xff0c;这时候低代码开发平台就能够发挥重要作用。 低代…

我们为什么还要学习Altium Designer?

Altium Designe&#xff08;简称“AD”&#xff09;是电子设计领域中备受推崇的软件工具之一&#xff0c;拥有强大的功能和灵活的设计环境&#xff0c;也是要用最广泛的EDA工具之一&#xff0c;为电子工程师提供了无限可能&#xff0c;但很多工程师学完AD基本操作就转投其他EDA…

支付宝小程序打包成APP

发行——原生App-云打包——填写安卓包的信息&#xff08;安卓证书可在香蕉云编下载&#xff09;——打包——下载APK 第一步&#xff1a;点击菜单栏发行 第二步&#xff1a;选择远程APP-云打包 第三步&#xff1a;在香蕉云编&#xff08;https://www.yunedit.com/&#xff0…

K8S之yaml文件,声明式管理方法

目录 第一章.声明式管理方法 1.1.声明式管理方法 1.2.kubectl create 和 kubectl apply区别 1.3.查看资源配置清单 1.4.解释资源配置清单 1.5.修改资源配置清单并应用 第二章.yaml文件格式 2.1.yaml文件简述 2.2.YAML 语法格式 2.3.查看 api 资源版本标签 2.4.写一个…

MVC中Controller向View传值的几种方式

MVC中Controller向View传值的几种方式 文章目录 MVC中Controller向View传值的几种方式一、ViewModel使用ViewModel 二、ViewData在控制器和视图间使用ViewData传递数据在 ViewDataTest 视图中使用ViewData的数据在视图和部分视图间使用ViewData 三、ViewBag四、TempData五、Ses…

搭建短链服务

目录 一、背景 1.1短链接的优势 1.1.1优点一 1.1.2优点二 1.1.3优点三 1.1.4优点四 1.1.4优点五 二、原理 2.1利用http重定向 3.1实现方案 3.1.1发号器实现 3.1.2存储实现 3.1.3映射实现 3.2架构图 一、背景 短链在互联网中盛行&#xff0c;搭建自己短链平台&…

硬件工程师-MOS管

MOSFET 场效应管 N管 P管 对标三极管 N管 P管 三极管具有功率放大的作用 MOSFET也具有功率作用&#xff0c; 控制级的电流很小 控制信号的内阻大 输出级的电流很大 输出信号的内阻很小 三极管的缺点&#xff1a;流控…

Blender 建模键盘(PS修图、UV贴图、Cycles渲染引擎)

目录 1. 键盘模型1.1 键盘底座1.2 底座细节1.3 logo位置1.4 键盘按键1.5 按键添加1.6 合并按键 2. 贴图、渲染2.1 到PS添加按键文字2.2 保存png图片2.3 图像纹理2.4 UV编辑2.5 添加平面2.6 添加环境纹理2.7 灯光、摄像机2.8 渲染属性2.9 渲染出图 1. 键盘模型 原图 1.1 键盘底…

三、IOC容器(2)

四、IOC操作Bean管理&#xff08;xml注入集合属性&#xff09; 4.在集合里面设置对象类型值 ①Course类 ②Stu类 ③配置xml文件 ④测试 5.把集合注入部分提取出来 在Spring配置文件中引入名称空间 util 2.使用util标签完成list集合注入 ①提取list集合类型的属性注入 <…

如何调整碳化硅 MOSFET 驱动来减少功率损耗

如何调整碳化硅 MOSFET 驱动来减少功率损耗 1.如何减少传导损耗&#xff1f;2.如何减少开关损耗&#xff1f;2.1 关断损耗 (Eoff) 取决于 Rg 和 Vgs-off2.2 开通损耗 (Eon) vs. Rg2.3 开通损耗 Eon 和反向恢复损耗 Err 的米勒效应2.4 对驱动电流的要求 作者&#xff1a;Xiou 参…

销售/回收DSOS254A是德keysight MSOS254A混合信号示波器

Agilent DSOS254A、Keysight MSOS254A、 混合信号示波器&#xff0c;2.5 GHz&#xff0c;20 GSa/s&#xff0c;4 通道&#xff0c;16 数字通道。 ​Infiniium S 系列示波器 信号保真度方面树立新标杆 500 MHz 至 8 GHz 出色的信号完整性使您可以看到真实显示的信号&#xff1…

远程桌面连接不上解决方法

远程桌面连接是一种方便快捷的技术&#xff0c;可以让用户在不同的设备之间共享桌面和访问远程计算机。然而&#xff0c;有时候我们可能会遇到远程桌面连接无法正常连接的问题。在本篇文章中&#xff0c;我们将详细介绍远程桌面连接无法连接的常见原因&#xff0c;并提供相对应…

0601-指针的基础

内存 物理存储器和存储地址空间 物理存储器&#xff1a;实际存在的具体存储器芯片。比如&#xff1a;内存条、RAM芯片、ROM芯片。 存储地址空间&#xff1a;对存储器编码的范围。 编码&#xff1a;对每个物理存储单元&#xff08;一个字节&#xff09;分配一个号码寻址&…

520网络情人节:用双语告白你的女神男神!

网络情人节&#xff08;Network Valentines Day&#xff09;——520、521被喻为“我愿意、我爱你” 的意思&#xff0c;又被称为“结婚吉日”、“表白日”、“撒娇日”、“求爱节”。每年5月20日和5月21日的“网络情人节”也成为了情侣们扎堆登记结婚、隆重举办婚宴 的吉日。 5…

系统分析师经典易错题,解题思路一

数据库通常采用三级模式结构,其中,视图对应外模式,基本表对应模式,存储文件对应内模式。数据的独立性是由DBMS的二级映像功能来保证的。数据的独立性包括数据的物理独立性和数据逻辑独立性。数据的物理独立性是指当数据库的内模式发生改变时,数据的逻辑结构不变。为了保证…

HTML获取SpringBoot从model传的值

controller层如下&#xff1a; html获取格式&#xff1a;[[${传入的值}]] 效果图&#xff1a;

Mybatis操作数据库执行流程的先后顺序是怎样的?

MyBatis是一个支持普通SQL查询、存储及高级映射的持久层框架&#xff0c;它几乎消除了JDBC的冗余代码。使Java开发人员可以使用面向对象的编程思想来操作数据库。对于MyBatis的工作原理和操作流程的理解&#xff0c;我们先来看下面的工作流程图。 MaBatis的工作流程 在上图中…