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

[算法] 第二集 二叉树中的深度搜索

深度优先遍历(DFS,全称为 Depth First Traversal),是我们树或者图这样的数据结构中常⽤的
⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分支,直到⼀条路径上的所有节点都被遍历
完毕,然后再回溯到上⼀层,继续找⼀条路遍历。
在⼆叉树中,常见的深度优先遍历为:前序遍历、中序遍历以及后序遍历。
因为树的定义本⾝就是递归定义,因此采⽤递归的方法去实现树的三种遍历不仅容易理解⽽且代码很简洁。并且前中后序三种遍历的唯⼀区别就是访问根节点的时机不同,在做题的时候,选择⼀个适当的遍历顺序,对于算法的理解是非常有帮助的。

一、计算布尔二叉树的值

1.题目描述

2.算法思路

书面解释就是:

1. 对于规模为 n 的问题,需要求得当前节点值。
2. 节点值不为 0 或 1 时,规模为 n 的问题可以被拆分为规模为 n-1 的子问题:
a. 所有子节点的值;
b. 通过子节点的值运算出当前节点值。
3. 当问题的规模变为 n=1 时,即叶⼦节点的值为 0 或 1,我们可以直接获取当前节点值为 0 或 1。
画图来理解一下:
我们如果想知道根节点true or false,我们需要知道其子节点,true or false,进而层层递归

3.代码实现

class Solution
{
public:bool evaluateTree(TreeNode* root) {if(root->left == nullptr) {return root->val == 0 ? false : true;}bool left = evaluateTree(root->left);bool right = evaluateTree(root->right);return root->val == 2 ? left | right : left & right;}
};

二、求根节点到叶节点数字之和

1.题目描述

2.算法思路

通过前序遍历,往左右子树传递信息,并且在回溯时得到左右子树的返回值。让递归函数完成两件事:
1. 将父节点的数字与当前节点的信息整合到⼀起,计算出当前节点的数字,然后传递到下⼀层进行递归;
2. 当遇到叶子节点的时候,就不再向下传递信息,将整合的结果向上⼀直回溯到根节点。
在递归结束时,根节点需要返回的值也就被更新为了整棵树的数字和。
递归函数设计:int dfs(TreeNode* root, int num)
1. 返回值:当前子树计算的结果(数字和);
2. 参数 num:递归过程中往下传递的信息(父节点的数字);
3. 函数作用:整合父节点的信息与当前节点的信息计算当前节点数字,并向下传递,再回溯时返回当前子树(当前节点作为子树根节点)数字和。
我们画图来理解一下,举个例子:
我们有如下二叉树
首先,我们 合父节点的信息与当前节点的信息计算当前节点数字,并向下传递:
溯时返回当前子树(当前节点作为子树根节点)数字和:
最后返回计算的和就行了
递归函数流程:
1. 当遇到空节点的时候,说明这条路从根节点开始没有分⽀,返回 0;
2. 结合⽗节点传下的信息以及当前节点的 val,计算出当前节点数字 sum;
3. 如果当前结点是叶子节点,直接返回整合后的结果 sum;
4. 如果当前结点不是叶父节点,将 sum 传到左右子树中去,得到左右子树中节点路径的数字和,然 后相加后返回结果。

3.代码实现

class Solution {
public:int dfs(TreeNode* root, int prevSum) {if (root == nullptr) {return 0;}int sum = prevSum * 10 + root->val;if (root->left == nullptr && root->right == nullptr) {return sum;} else {return dfs(root->left, sum) + dfs(root->right, sum);}}int sumNumbers(TreeNode* root) {return dfs(root, 0);}
};

三、二叉树剪枝

1.题目描述

2.算法思路

如果我们选择从上往下删除,我们需要收集左右⼦树的信息,这可能导致代码编写相对困难。然而, 通过观察我们可以发现,如果我们先删除最底部的叶子节点,然后再处理删除后的节点,最终的结果并不会受到影响。 因此,我们可以采⽤后序遍历的方式来解决这个问题。在后序遍历中,我们先处理左子树,然后处理 右子树,最后再处理当前节点。在处理当前节点时,我们可以判断其是否为叶子节点且其值是否为 0,
如果满足条件,我们可以删除当前节点。
• 需要注意的是,在删除叶子节点时,其父节点很可能会成为新的叶子节点。因此,在处理完子节点后,我们仍然需要处理当前节点。这也是为什么选择后序遍历的原因(后序遍历⾸先遍历到的一定是叶子节点)。
• 通过使用后序遍历,我们可以逐步删除叶子节点,并且保证删除后的节点仍然满足删除操作的要
求。这样,我们可以较为方便地实现删除操作,而不会影响最终的结果。
• 若在处 理结束后所有叶子节点的值均为 1,则所有子树均包含 1,此时可以返回。
算法流程:
递归函数设计:void dfs(TreeNode*& root)
1. 返回值:无;
2. 参数 :当前需要处理的节点;
3. 函数作用:判断当前节点是否需要删除,若需要删除,则删除当前节点。
后序遍历的主要流程:
1. 递归出口:当传入节点为空时,不做任何处理;
2. 递归处理左子树;
3. 递归处理右子树;
4. 处理当前节点:判断该节点是否为叶⼦节点(即左右⼦节点均被删除,当前节点成为叶子节点),
并且节点的值为 0:
a. 如果是,就删除掉;
b. 如果不是,就不做任何处理。

3.代码实现:

class Solution
{
public:TreeNode* pruneTree(TreeNode* root) {if(root == nullptr) return nullptr;root->left = pruneTree(root->left);root->right = pruneTree(root->right);if(root->left == nullptr && root->right == nullptr && root->val == 0){delete root; // 防⽌内泄漏root = nullptr;}return root;}
};

四、验证二叉搜索树

1.题目描述

2.算法思路

 如果一棵树是二叉搜索树,那么它的中序遍历的结果一定是⼀个严格递增的序列。 因此,我们可以初始化⼀个无穷小的全区变量,用来记录中序遍历过程中的前驱结点。那么就可以在中序遍历的过程中,先判断是否和前驱结点构成递增序列,然后修改前驱结点为当前结点,传入下一层的递归中。
算法流程:
  1.  初始化⼀个全局的变量 prev,⽤来记录中序遍历过程中的前驱结点的 val;
  2.  中序遍历的递归函数中:
    a. 设置递归出⼝:root == nullptr 的时候,返回 true;
    b. 先递归判断左⼦树是否是⼆叉搜索树,⽤ retleft 标记;
    c. 然后判断当前结点是否满⾜⼆叉搜索树的性质,用 retcur 标记:
    ▪ 如果当前结点的 val ⼤于 prev,说明满足条件,retcur 改为 true;
    ▪ 如果当前结点的 val ⼩于等于 prev,说明不满⾜条件,retcur 改为 false;
    d. 最后递归判断右⼦树是否是⼆叉搜索树,⽤ retright 标记;
  3. 只有当 retleft、 retcur 和 retright 都是 true 的时候,才返回 true。

3.代码实现

class Solution 
{
public:long prev = LONG_MIN;bool isValidBST(TreeNode* root) {if(root == nullptr) return true;bool left = isValidBST(root->left);// 剪枝if(left == false) return false;bool cur = false;if(root->val > prev)cur = true;// 剪枝if(cur == false) return false;prev = root->val;bool right = isValidBST(root->right);return left && right && cur;}
};​

感谢大家的观看,如有错误欢迎指正!

相关文章:

[算法] 第二集 二叉树中的深度搜索

深度优先遍历(DFS,全称为 Depth First Traversal),是我们树或者图这样的数据结构中常⽤的 ⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分支,直到⼀条路径上的所有节点都被遍历 完毕,然后再回溯到上…...

放弃使用外键时,sequelize 应该怎么使用?

在使用 Sequelize 时,如果想放弃使用外键,但仍然希望在模型之间建立关联,可以通过设置 constraints 选项为 false 来实现。这允许你定义模型之间的关系,而不在数据库中创建外键约束。以下是具体的实现步骤: 定义没有外…...

Microsoft GraphRAG 输出的配置信息

Microsoft GraphRAG 输出的配置信息 {"llm": {"api_key": "REDACTED, length 9","type": "oci_genai_chat","model": "cohere.command-r-plus","max_tokens": 4000,"temperature"…...

怎么判断张量的维度(形状(shape)),即如何定义行数、列数和深度的?

举一个三维张量吧 # 3行4列深度为2 const3 tf.constant([[[1,2],[3,4],[5,6],[7,8]],[[11, 12], [13, 14], [15, 16], [17, 18]],[[21, 22], [23, 24], [25, 26], [27, 28]] ],tf.float16) shape (3,4,2)--借鉴博主奶油松果的图和代码 分析形状 (3, 4, 2) 最外层的括号&…...

AI入门指南(二):算法、训练、模型、大模型是什么?

文章目录 一、前言二、算法是什么?概念实际应用 三、训练是什么?概念实际应用 四、模型是什么?概念实际应用小结 五、大模型是什么?概念大模型和小模型有什么区别?大模型分类实际应用 六、总结七、参考资料 一、前言 …...

CSS已访问链接的隐私保护

摘抄自:《CSS权威指南 第四版》 有超过十年的时间,已访问的链接可以使用任何可用的CSS属性装饰,与未访问链接没有差别。 然而,大约在2005年,有几个人通过示例揭露,通过视觉样式和简单的DOM脚本就可以判断用…...

代码练习12-排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 归并排序算法核心步骤 归并排序核心步骤如下: 把长度为n的要排序的序列,分成两个长度为n/2的子序列;对这两个子序列,分别采用归并排序&#xff1b…...

Linux 内核源码分析---套接字

套接字通信 ISO 设计一种参考模型,定义组成网络的各个层,该模型由7层组成,称为OSI(开放 系统互连)模型如下: 应用层:网络服务与最终用户的接口; 表示层:数据的表示、安…...

vscode配置xdebug断点调试详细教程

注:环境为本地windows开发环境,编辑器为vscode,PHP集成环境工具为EServer vscode安装扩展并配置 安装PHP Debug 扩展中搜索 PHP Debug 并安装: 配置PHP Debug 1、点击扩展设置 2、在设置中,点击 setting.json 3、编…...

【人工智能】Transformers之Pipeline(八):文生图/图生图(text-to-image/image-to-image)

目录 一、引言 二、文生图/图生图(text-to-image/image-to-image) 2.1 文生图 2.2 图生图 2.3 技术原理 2.3.1 Diffusion扩散模型原理 2.3.2 Stable Diffusion扩散模型原理 2.4 文生图实战 2.4.1 SDXL 1.0 2.4.2 SD 2.0 2.5 模型排名 三、总…...

AI Agent 工程师认证-学习笔记(1)——【单Agent】ModelScope-Agent

学习链接: 【单Agent】ModelScope-Agent学习指南https://datawhaler.feishu.cn/wiki/GhOLwvAPkiSWmokjUgqc1eGonDf 手把手Agent开发开源教程(觉得不错的话可以star一下)https://github.com/datawhalechina/agent-tutorial 动手学Agent应用…...

【Python机器学习】树回归——将CART算法用于回归

要对数据的复杂关系建模,可以借用树结构来帮助切分数据,如何实现数据的切分?怎样才能知道是否已经充分切分?这些问题的答案取决于叶节点的建模方式。回归树假设叶节点是常数值,这种策略认为数据中的复杂关系可以用树结…...

前端(HTML + CSS)小兔鲜儿项目(仿)

前言 这是一个简单的商城网站,代码部分为HTML CSS 和少量JS代码 项目总览 一、头部区域 头部的 购物车 和 手机 用的是 文字图标,所以效果可以和文字一样 购物车右上角用的是绝对定位 logo用的是 h1 标签,用来提高网站搜索排名 二、banne…...

【Rust光年纪】构建高效终端用户界面:Rust库全面解析

构建优雅终端应用:深度评析六大Rust库 前言 随着Rust语言的流行和应用场景的不断扩大,对于终端操作和用户界面构建的需求也日益增长。本文将介绍一些在Rust语言中常用的终端操作库和用户界面构建库,以及它们的核心功能、使用场景、安装与配…...

鼠标滑动选中表格部分数据列(vue指令)

文章目录 代码指令代码使用代码 代码 指令代码 // 获得鼠标移动的范围 function getMoveRange(startClientX, endClientX, startClientY, endClientY) {const _startClientX Math.min(startClientX, endClientX);const _endClientX Math.max(startClientX, endClientX);con…...

“5G+Windows”推动全场景数字化升级:美格智能5G智能模组SRM930成功运行Windows 11系统

操作系统作为连接用户与数字世界的桥梁,在数字化迅速发展的时代扮演着至关重要的角色,智能设备与操作系统的协同工作,成为推动现代生活和商业效率的关键力量。其中,Windows系统以其广泛的应用基础和强大的兼容性成为全球最广泛使用…...

c语言学习,isupper()函数分析

1:isupper() 函数说明: 检查参数c,是否为大写英文字母。 2:函数原型: int isupper(int c) 3:函数参数: 参数c,为检测整数 4:返回值: 参数c是大写英文字母&…...

Adnroid 数据存储:SharedPreferences详解【SharedPreferencesUtils,SharedPreferences的ANR】

目录 1)SP是什么、如何使用,SPUtils 2)SP的流程 3)comit和apply 一、SP是什么,如何使用,SPUtils 1.1 SP是什么? SharedPreferences是Android平台提供的一种轻量级的数据存储方式,…...

Sentinel 规则持久化到 Nacos 实战

前言: 前面系列文章我们对 Sentinel 的作用及工作流程源码进行了分析,我们知道 Sentinel 的众多功能都是通过规则配置完成的,但是我们前面在演示的时候,发现 Sentinel 一重启,配置的规则就没有了,这是因为…...

服务器CPU天梯图2024年8月,含EYPC/至强及E3/E5

原文地址&#xff08;高清无水印原图/持续更新/含榜单出处链接&#xff09;&#xff1a; >>>服务器CPU天梯图<<< 本文提供的服务器CPU天梯图数据均采集自各大专业网站&#xff0c;榜单图片末尾会标准其来源&#xff08;挂太多链接有概率会被ban&#xff0c;…...

STM32自动循迹小车设计与实现

1. 项目概述2016年TI杯电子设计竞赛中&#xff0c;我们团队设计了一款基于STM32的自动循迹小车系统。这个项目获得了省级一等奖&#xff0c;也是我职业生涯的重要转折点。作为控制类题目&#xff0c;系统需要实现沿预定轨迹自动行驶&#xff0c;并能检测轨迹旁的金属硬币。核心…...

强化学习反噬:模型为骗奖励毁掉生产环境

从游戏作弊到生产事故在软件测试领域&#xff0c;我们习惯于与确定性缺陷作斗争&#xff1a;空指针、内存泄漏、逻辑错误。然而&#xff0c;随着人工智能&#xff0c;特别是强化学习&#xff08;Reinforcement Learning, RL&#xff09;模型被集成到生产系统&#xff08;如自动…...

计算机毕业设计springboot展会门票系统 基于SpringBoot的会展票务数字化服务平台 SpringBoot框架下的博览会入场券预约与核销系统

计算机毕业设计springboot展会门票系统 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着会展经济的蓬勃发展和数字化转型的深入推进&#xff0c;各类展会活动规模不断扩大&am…...

WandEnhancer终极指南:WeMod本地增强与功能解锁的完整实践

WandEnhancer终极指南&#xff1a;WeMod本地增强与功能解锁的完整实践 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer WandEnhancer是一款专为WeMod客户…...

DocHub二次开发指南:自定义功能扩展与API集成

DocHub二次开发指南&#xff1a;自定义功能扩展与API集成 【免费下载链接】DocHub 参考百度文库&#xff0c;使用Beego&#xff08;Golang&#xff09;开发的开源文库系统 项目地址: https://gitcode.com/gh_mirrors/do/DocHub DocHub是基于Beego框架&#xff08;Golang…...

小米设备集成终极测试指南:确保HomeAssistant稳定运行的7个关键步骤

小米设备集成终极测试指南&#xff1a;确保HomeAssistant稳定运行的7个关键步骤 【免费下载链接】hass-xiaomi-miot Automatic integrate all Xiaomi devices to HomeAssistant via miot-spec, support Wi-Fi, BLE, ZigBee devices. 小米米家智能家居设备接入Hass集成 项目地…...

LangChain消息系统深度解析:从OpenAI格式到Claude 3.5,如何设计一个健壮的对话状态机?

LangChain消息系统架构设计&#xff1a;构建企业级对话状态机的工程实践 在当今AI应用开发领域&#xff0c;对话系统的复杂度和功能性需求正呈指数级增长。从简单的单轮问答到需要维护长期记忆、处理多模态输入、执行工具调用的复杂Agent系统&#xff0c;开发者面临的挑战已远超…...

PX4飞控Telem2接口详解:除了连树莓派,还能怎么玩?(附QGC参数配置清单)

PX4飞控Telem2接口的进阶玩法&#xff1a;解锁隐藏功能的6种实战方案 在无人机开发领域&#xff0c;Pixhawk飞控的Telem2接口常被简单当作连接树莓派或Jetson的通信通道。但当我第一次测量到这个接口的VCC引脚居然能稳定输出5V/500mA时&#xff0c;一个大胆的想法浮现&#xff…...

当Excel图表无法表达你的数据故事时:Charticulator开启零代码可视化创作新纪元

当Excel图表无法表达你的数据故事时&#xff1a;Charticulator开启零代码可视化创作新纪元 【免费下载链接】charticulator Interactive Layout-Aware Construction of Bespoke Charts 项目地址: https://gitcode.com/gh_mirrors/ch/charticulator 问题&#xff1a;数据…...

如何用CodeMaker将Java/Scala开发效率提升300%?5个核心技巧带你掌握智能代码生成

如何用CodeMaker将Java/Scala开发效率提升300%&#xff1f;5个核心技巧带你掌握智能代码生成 【免费下载链接】CodeMaker A idea-plugin for Java/Scala, support custom code template. 项目地址: https://gitcode.com/gh_mirrors/co/CodeMaker 作为Java/Scala开发者&a…...