leetcode题解513:找树左下角的值(递归中的回溯处理)!

一、题目内容:

题目要求找到一个二叉树的最底层最左边节点的值。具体来说,我们需要从根节点开始遍历二叉

树,找到最深的那层中的最左边的节点,并返回该节点的值。因为要先找到最底层左侧的值,所以我们选择遍历顺序一定是左侧先遍历,右侧后遍历。

我们需要声明depth、MaxDepth和result,depth记录当前深度、MaxDepth记录最大深度深度、result记录深度最大值,但在遍历中我么会思考到,如果遍历到某一叶子节点,但是当前结点深度并不是最大的,那么递归会回退到其父结点,这时就需要将深度回溯,这一过程如何实现呢,我们会在代码中体现。

二、题目分析

输入和输出

  • 输入:二叉树的根节点 root

    • 二叉树的每个节点是一个 TreeNode 对象,包含:

      • val:节点的值(整数)。

      • left:指向左子节点的指针。

      • right:指向右子节点的指针。

  • 输出:最底层最左边节点的值(整数)。

深度优先遍历函数 trevesal

  • 参数

    • root:当前节点。

    • depth:当前节点的深度。

  • 逻辑

    • 如果当前节点是叶子节点(即没有左子节点和右子节点)则:

      • 如果当前深度 depth 大于 maxDepth,则更新 maxDepthresult

    • 如果当前节点有左子节点则:

      • 递归调用 trevesal,深度加1。

    • 如果当前节点有右子节点则:

      • 递归调用 trevesal,深度加1。

    • 回溯:在递归调用结束后,深度减1,以恢复到当前节点的深度。

三、代码解答

1.C++代码

class Solution {
public:int maxDepth = INT_MIN;  // 用于记录当前找到的最深的叶子节点的深度int result;              // 用于存储最底层最左边节点的值// 定义递归函数,用于深度优先搜索void trevesal(TreeNode *root, int depth) {// 如果当前节点是叶子节点(没有左子节点和右子节点)if (root->left == NULL && root->right == NULL) {// 如果当前深度大于已知的最大深度if (depth > maxDepth) {result = root->val;  // 更新结果值为当前节点的值maxDepth = depth;    // 更新最大深度为当前深度}}// 如果当前节点有左子节点if (root->left) {depth++;  // 深度加1,进入下一层trevesal(root->left, depth);  // 递归遍历左子节点depth--;  // 回溯,恢复到当前节点的深度}// 如果当前节点有右子节点if (root->right) {depth++;  // 深度加1,进入下一层trevesal(root->right, depth);  // 递归遍历右子节点depth--;  // 回溯,恢复到当前节点的深度}}// 主函数,用于调用递归函数并返回结果int findBottomLeftValue(TreeNode* root) {trevesal(root, 0);  // 从根节点开始,深度为0return result;      // 返回最底层最左边节点的值}
};

详细注释

1. 成员变量
int maxDepth = INT_MIN;  // 初始化为最小整数,表示当前找到的最深的叶子节点的深度
int result;              // 用于存储最底层最左边节点的值
  • maxDepth:记录当前找到的最深的叶子节点的深度,初始值为 INT_MIN,确保任何叶子节点的深度都会比它大。

  • result:存储最底层最左边节点的值,初始值未定义,会在递归过程中被赋值。

2. 递归函数 trevesal
void trevesal(TreeNode *root, int depth) {// 如果当前节点是叶子节点(没有左子节点和右子节点)if (root->left == NULL && root->right == NULL) {// 如果当前深度大于已知的最大深度if (depth > maxDepth) {result = root->val;  // 更新结果值为当前节点的值maxDepth = depth;    // 更新最大深度为当前深度}}// 如果当前节点有左子节点if (root->left) {depth++;  // 深度加1,进入下一层trevesal(root->left, depth);  // 递归遍历左子节点depth--;  // 回溯,恢复到当前节点的深度}// 如果当前节点有右子节点if (root->right) {depth++;  // 深度加1,进入下一层trevesal(root->right, depth);  // 递归遍历右子节点depth--;  // 回溯,恢复到当前节点的深度}
}
  • 叶子节点检查

    • 如果当前节点没有左子节点和右子节点,说明它是一个叶子节点。

    • 如果当前叶子节点的深度大于已知的最大深度 maxDepth,则更新 resultmaxDepth

  • 递归遍历左子节点

    • 如果当前节点有左子节点,深度加1,递归调用 trevesal 遍历左子节点。

    • 递归返回后,深度减1,恢复到当前节点的深度。这是回溯的关键步骤,确保每次递归返回后,深度值正确。

  • 递归遍历右子节点

    • 如果当前节点有右子节点,深度加1,递归调用 trevesal 遍历右子节点。

    • 递归返回后,深度减1,恢复到当前节点的深度。同样,这是回溯的关键步骤。

3. 主函数 findBottomLeftValue
int findBottomLeftValue(TreeNode* root) {trevesal(root, 0);  // 从根节点开始,深度为0return result;      // 返回最底层最左边节点的值
}
  • 调用递归函数

    • 从根节点开始,初始深度为0,调用 trevesal 函数。

  • 返回结果

    • 递归完成后,返回 result,即最底层最左边节点的值。

回溯和递归的详细解释

递归
  • 递归是一种函数调用自身的方法,用于解决复杂问题。在本题中,递归用于遍历二叉树的每个节点。

  • 每次递归调用时,深度 depth 增加1,表示进入下一层。

  • 递归调用的终止条件是当前节点是叶子节点(没有左子节点和右子节点)。

回溯
  • 回溯是一种在递归调用返回后恢复状态的机制。

  • 在本题中,每次递归调用返回后,深度 depth 减1,恢复到当前节点的深度。

  • 这样可以确保每次递归返回后,深度值正确,不会影响后续的递归调用。

示例

假设二叉树如下:

    1/ \2   3/   / \
4   5   6
遍历过程
  1. 从根节点 1 开始,深度为0。

    • 调用 trevesal(1, 0)

  2. 遍历左子节点 2,深度为1。

    • 调用 trevesal(2, 1)

  3. 遍历左子节点 4,深度为2。

    • 调用 trevesal(4, 2)

    • 4 是叶子节点,且深度大于 maxDepth,更新 maxDepth=2result=4

    • 返回到节点 2,深度减1,恢复为1。

  4. 返回到根节点 1,深度减1,恢复为0。

  5. 遍历右子节点 3,深度为1。

    • 调用 trevesal(3, 1)

  6. 遍历左子节点 5,深度为2。

    • 调用 trevesal(5, 2)

    • 5 是叶子节点,但深度等于 maxDepth,不更新。

    • 返回到节点 3,深度减1,恢复为1。

  7. 遍历右子节点 6,深度为2。

    • 调用 trevesal(6, 2)

    • 6 是叶子节点,但深度等于 maxDepth,不更新。

    • 返回到节点 3,深度减1,恢复为1。

  8. 返回到根节点 1,深度减1,恢复为0。

最终,result=4,即最底层最左边的节点值。

总结

通过递归和回溯,代码能够有效地找到二叉树最底层最左边的节点值。递归用于遍历二叉树,回溯用于恢复状态,确保每次递归返回后,深度值正确。

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

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

相关文章

C#面试问题41-60

41. What is the Singleton design pattern? Singleton is a class that only allows creating a single instance of itselt. 单例设计模式是一个类,它只允许创建自己的单个实例。 构造函数防止他在单例类以外的地方被调用。 使用情景:need a sing…

笔记思考法

掌握麦肯锡流笔记术,对大家来说有以下几种好处: 1) 可以将自己的思考可视化,使之变得更加清晰 2) 避免无用功 3) 经常能够提出有创意的想法 4) 遇到问题时能够及时找到解决办法 5) 不管面对什么情况都能够找出真正有效的解决办法 为什么仅仅通过改变使用…

Rust 学习笔记:关于闭包的练习题

Rust 学习笔记:关于闭包的练习题 Rust 学习笔记:关于闭包的练习题问题 1问题 2以下程序能否通过编译?若能,输出是?以下程序能否通过编译?若能,输出是?考虑该 API,空白处填…

(一)微服务(垂直AP/分布式缓存/装饰器Pattern)

文章目录 项目地址一、创建第一个垂直API1.1 创建Common层1. ICommand接口2. IQuery接口 1.2 创建API1. 实体2. Handler3. endpoint 1.3 使用Marten作为ORM 二、Redis缓存2.1 使用缓存装饰器1. 创建装饰器2. 注册装饰器 2.2 创建docker-compose1. docker-compose2. docker-comp…

Spring AI系列之使用 Spring AI 转录音频文件(基于OpenAI)

概述 企业常常需要从各种类型的音频内容中提取有价值的数据,例如:将客户支持通话转录用于情感分析、为视频生成字幕,或整理会议纪要。然而,手动转录音频文件既耗时又昂贵。 为了解决这一问题,OpenAI 提供了强大的语…

室内VR全景助力房产营销及装修

在当今的地产行业,VR全景已成为不可或缺的应用工具。从地产直播到楼市VR地图,从效果图到水电家装施工记录,整个地产行业的上下游生态中,云VR全景的身影无处不在。本文将探讨VR全景在房产营销及装修领域的应用,并介绍众…

Sentinel限流熔断机制实战

1、核心概念 1.1、流量控制 流量控制是为了 防止系统被过多的请求压垮,确保资源合理分配并保持服务的可用性,比如对请求数量的限制。 流量控制的 3 个主要优势: 防止过载:当瞬间涌入的请求量超出系统处理能力时,会…

深度解析 torch.mean 的替代方案

torch.mean 是什么意思 代码效果解释 segment_vector = torch.mean(segment_embedding, dim=1) # [1, hidden_dim] 这行代码的作用是在指定维度上对张量 segment_embedding 求平均值,实现类似平均池化的效果。 具体来说,dim=1 表示沿着索引为1的维度进行操作。假设 segment…

Paraformer语音模型:一种语音模型加速方法

随着智能语音技术的普及,语音识别(ASR)、语音合成(TTS)、声纹识别等应用场景对模型推理效率提出了极高要求,本文介绍将Paraformer语音模型从预训练模型导出为ONNX格式,并使用ONNX Runtime进行推…

本地部署FreeGPT+内网穿透公网远程访问,搞定ChatGPT外网访问难题

‌FreeGPT‌是一个基于GPT 3.5/4的ChatGPT聊天网页用户界面,提供了一个开放的聊天界面,开箱即用‌。ChatGPT是非常热门的,但访问体验一直不太理想。为了解决这一问题,出现了各类方法和工具,其中FreeGPT是一款非常实用的…

ElasticSearch迁移至openGauss

Elasticsearch 作为一种高效的全文搜索引擎,广泛应用于实时搜索、日志分析等场景。而 openGauss,作为一款企业级关系型数据库,强调事务处理与数据一致性。那么,当这两者的应用场景和技术架构发生交集时,如何实现它们之…

品优购项目(HTML\CSS)

项目效果可访问 http://zhousunyu.3vdo.club 查看 主页 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…

因泰立科技:镭眸T51激光雷达,打造智能门控新生态

在高端门控行业&#xff0c;安全与效率是永恒的追求。如今&#xff0c;随着科技的飞速发展&#xff0c;激光雷达与TOF相机技术的融合&#xff0c;为门控系统带来了前所未有的智能感知能力&#xff0c;开启了精准守护的新时代。因泰立科技的镭眸T51激光雷达&#xff0c;作为这一…

MyBatisPlus--快速入门

MyBatisPlus介绍 从名字中就可以感觉到MybatisPlus与MyBatis之间的渊源&#xff0c;而MyBatis是一个非常流行的持久层框架&#xff0c;主要来做数据库的增删改查&#xff0c;而MyBatisPlus这种命名方式让人不得不往MyBatis的升级版去联想&#xff0c;事实也确实如此&#xff0…

redis持久化策略

RDB 是通过生成数据快照来实现持久化的&#xff0c;相当于给内存中的数据拍一张"照片"保存到磁盘上。AOF 记录所有写操作命令&#xff0c;以Redis协议格式追加到文件末尾。 RDB 在满足特定条件时触发内存快照&#xff0c;生成新的RDB文件替换旧文件 AOF 先写入内…

Spring Boot中使用@JsonAnyGetter和@JsonAnySetter处理动态JSON属性

Spring Boot 中使用 @JsonAnyGetter 和 @JsonAnySetter 处理动态 JSON 属性 在实际的后端开发中,尤其是使用 Spring Boot 构建 API 时,我们经常会遇到需要处理动态 JSON 属性的场景。例如,前端传递过来的 JSON 数据结构不固定,或者业务需求变更频繁,导致实体类无法预先定…

拉取gitlab项目

一、下载nvm管理node 先下载配置好nvm,再用nvm下载node 下载链接&#xff1a;开始 下载nvm - nvm中文官网 情况&#xff1a;npm i 下载依赖缓慢&#xff0c;可能是node版本不对&#xff0c;可能node版本太高 可能得问题&#xff1a;使用nvm 下载低版本的node时&#xff0c;…

【解决办法】ubuntu重启不起来,输入用户名和密码进不去,又重新返回登录页。

项目场景&#xff1a; ubuntu重启不起来&#xff0c;输入用户名和密码进不去&#xff0c;又重新返回登录页。 问题描述 在华硕天选一代笔记本上面安装了ubuntu22.04.5桌面版&#xff0c;但是重启以后出现&#xff0c;输入了用户名和密码&#xff0c;等待一会还让输入用户名和…

# 云端大模型:智能时代的新引擎

云端大模型&#xff1a;智能时代的新引擎 在人工智能技术的迅猛发展中&#xff0c;云端大模型扮演着至关重要的角色。它们不仅推动了技术的边界&#xff0c;也为各行各业带来了前所未有的机遇。本文将结合一系列图片和代码示例&#xff0c;深入探讨云端大模型的功能、应用及其…

(1)pytest简介和环境准备

1. pytest简介 pytest是python的一种单元测试框架&#xff0c;与python自带的unittest测试框架类似&#xff0c;但是比unittest框架使用起来更简洁&#xff0c;效率更高。根据pytest的官方网站介绍&#xff0c;它具有如下特点&#xff1a; 非常容易上手&#xff0c;入门简单&a…