leetcode513.找树左下角的值:递归深度优先搜索中的最左节点追踪之道

一、题目本质与核心诉求解析

在二叉树算法问题中,"找树左下角的值"是一个典型的结合深度与位置判断的问题。题目要求我们找到二叉树中最深层最左边的节点值,这里的"左下角"有两个关键限定:

  • 深度优先:必须是深度最大的那一层节点
  • 最左优先:在最深层中选择最左边的那个节点

先来看一个示例二叉树:

    1/ \2   3/   / \
4   5   6/7

在这个树中,最深层是第3层(根节点为第0层时是第2层),该层最左节点是7,因此正确输出为7。理解这个问题的核心在于如何在递归过程中同时追踪节点深度和左右位置关系,这也是本文要重点解析的内容。

二、递归解法的核心实现与数据结构设计

完整递归代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {private int Deep = -1;  // 记录当前最大深度private int res = 0;    // 记录最深层最左节点值public int findBottomLeftValue(TreeNode root) {findLeftVal(root, 0);  // 从根节点开始,深度初始为0return res;}public void findLeftVal(TreeNode root, int deep) {if (root == null) {return;}// 处理叶子节点:判断是否更新最深层最左节点if (root.left == null && root.right == null) {if (deep > Deep) {res = root.val;Deep = deep;}return;}// 先递归左子树,保证左子树优先访问if (root.left != null) {findLeftVal(root.left, deep + 1);}// 再递归右子树if (root.right != null) {findLeftVal(root.right, deep + 1);}}
}

关键数据结构设计解析

  1. Deep变量

    • 作用:记录当前发现的最大深度
    • 初始值:-1(因为根节点深度从0开始,确保第一个叶子节点会更新该值)
    • 更新时机:当遇到更深的叶子节点时更新
  2. res变量

    • 作用:存储最深层最左节点的值
    • 更新原则:仅当遇到更深的叶子节点,或者同深度但更左的叶子节点时更新(由于先左后右递归,同深度下左节点必然先访问)
  3. deep参数

    • 作用:当前递归层的节点深度
    • 传递方式:每次递归进入子节点时深度+1
    • 意义:明确当前节点在树中的层级位置

三、核心问题解析:递归中如何判断最深层最左节点

1. 深度优先搜索的顺序控制

本算法采用先左后右的深度优先搜索顺序,这是确保找到"最左"节点的关键:

  • 递归调用顺序:先处理左子树,再处理右子树
  • 核心逻辑:在同一深度下,左子树的节点会比右子树的节点先被访问
  • 效果:当存在多个同深度节点时,左节点会优先被判定为当前最深层最左节点

2. 深度判断与更新机制

if (root.left == null && root.right == null) {if (deep > Deep) {res = root.val;Deep = deep;}
}
  • 叶子节点判断:当节点左右子树都为空时,确定为叶子节点
  • 深度比较:如果当前叶子节点深度大于已记录的最大深度Deep,则更新结果
  • 更新策略
    1. 更深的叶子节点:直接更新res和Deep
    2. 同深度的叶子节点:由于先左后右递归,左节点先访问,res不会被右节点覆盖

3. 递归终止与回溯逻辑

  • 终止条件
    1. 遇到空节点时直接返回(递归边界)
    2. 处理完叶子节点后返回(不再继续递归)
  • 回溯作用:当左子树递归完成后,回溯到父节点,再进入右子树递归,确保左右子树都被遍历

四、递归流程深度模拟:以示例二叉树为例

示例二叉树结构(根节点深度为0):

    1(0)/   \2(1)  3(1)/     / \
4(2)  5(2) 6(2)/7(3)

详细递归执行过程

  1. 初始状态

    • Deep = -1, res = 0
    • 调用findLeftVal(root, 0),root为节点1,深度0
  2. 处理节点1(深度0)

    • 非叶子节点,进入左子树调用findLeftVal(2, 1)
  3. 处理节点2(深度1)

    • 非叶子节点,进入左子树调用findLeftVal(4, 2)
  4. 处理节点4(深度2)

    • 是叶子节点(左右子树为空)
    • 深度2 > Deep(-1),更新res=4, Deep=2
    • 返回上一层(节点2)
  5. 节点2的右子树为空,返回上一层(节点1)

  6. 节点1进入右子树调用findLeftVal(3, 1)

  7. 处理节点3(深度1)

    • 非叶子节点,进入左子树调用findLeftVal(5, 2)
  8. 处理节点5(深度2)

    • 非叶子节点,进入左子树调用findLeftVal(7, 3)
  9. 处理节点7(深度3)

    • 是叶子节点
    • 深度3 > Deep(2),更新res=7, Deep=3
    • 返回上一层(节点5)
  10. 节点5的右子树为空,返回上一层(节点3)

  11. 节点3进入右子树调用findLeftVal(6, 2)

  12. 处理节点6(深度2)

    • 是叶子节点
    • 深度2 < Deep(3),不更新res
    • 返回上一层(节点3)
  13. 所有递归结束,返回res=7

五、算法复杂度与递归特性分析

1. 时间复杂度分析

  • O(n):每个节点仅被访问一次,n为树的节点总数
  • 原因:递归过程中对每个节点进行一次深度判断,无重复访问

2. 空间复杂度分析

  • O(h):h为树的高度,取决于递归栈的最大深度
  • 最坏情况:树退化为链表时,h=n,空间复杂度O(n)
  • 平均情况:平衡二叉树h=logn,空间复杂度O(logn)

3. 递归算法的优势与局限

优势局限
代码逻辑简洁,符合树的递归定义可能因栈溢出无法处理极大树
天然支持深度优先搜索顺序控制空间复杂度与树深度相关
先左后右的递归顺序自然实现"最左"优先调试相比迭代更困难

六、核心技术点总结:递归找最左节点的三大关键

1. 深度优先搜索顺序控制

  • 先左后右的递归顺序是实现"最左"优先的核心
  • 递归天然保证左子树先于右子树处理,确保同深度下左节点优先被访问

2. 深度追踪与比较机制

  • 通过参数传递当前深度,全局变量记录最大深度
  • 叶子节点处进行深度比较,确保只保留最深层节点

3. 优先更新策略

  • 深度更大时:无条件更新结果
  • 深度相同时:由于左子树先处理,结果不会被右节点覆盖
  • 实现了"深度优先,同深度左优先"的判定逻辑

七、拓展思考:递归与迭代解法的对比与适用场景

1. 与层序遍历迭代法的对比

方法核心思想时间复杂度空间复杂度优势场景
递归深度优先+先左后右O(n)O(h)代码简洁、树深度较小
迭代广度优先+层序处理O(n)O(m)(m为最大层宽度)处理极大树、避免栈溢出

2. 大厂面试中的策略建议

  • 当树深度较小时,递归解法更简洁高效
  • 当树可能很深时,应考虑迭代解法避免栈溢出
  • 面试中可先给出递归解法,再主动说明迭代优化方向

八、总结:递归解法的核心设计哲学

本递归算法通过"深度优先搜索+先左后右顺序+深度追踪"的组合策略,巧妙解决了找树左下角值的问题。其核心设计哲学包括:

  1. 深度优先的天然优势:递归天然适合深度优先搜索,能自然追踪节点深度
  2. 顺序控制的重要性:先左后右的递归顺序是实现"最左"优先的关键
  3. 状态传递的巧妙设计:通过参数传递深度,全局变量记录结果,实现状态追踪
  4. 叶子节点的关键作用:仅在叶子节点处判断是否更新结果,提高算法效率

理解这种递归设计思路,不仅能解决本题,还能为类似的二叉树深度与位置相关问题提供通用解法。在实际应用中,可根据树的规模和场景选择递归或迭代实现,灵活应对不同需求。

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

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

相关文章

Python入门手册:Python基础语法

Python是一种简洁、易读且功能强大的编程语言&#xff0c;非常适合初学者入门。无论你是编程新手&#xff0c;还是有一定编程基础但想学习Python的开发者&#xff0c;掌握Python的基础语法都是迈向高效编程的第一步。本文将详细介绍Python的基本语法&#xff0c;包括变量和数据…

postgresql 常用参数配置

#01 - Connection-Authentication 优化点&#xff1a; listen_addresses 0.0.0.0 建议&#xff1a;生产环境应限制为具体IP&#xff08;如 192.168.1.0/24,127.0.0.1&#xff09;&#xff0c;避免暴露到公网。 ssl off 建议&#xff1a;启用SSL&#xff08;ssl on&#xf…

POI模板生成EXCEL 64000 style in a .xlsx Workbook

业务场景&#xff1a; 项目需要生成多个EXCEL表格&#xff0c;每个表格根据数据列表的大小动态增加Excel的行数&#xff0c;要保证新插入行的样式与模板完全一致 考虑使用以下方法保证样式的统一 cloneStyleFrom(templateStyle); 但是由于数据量比较大&#xff0c;抛出如下的…

HJ106 字符逆序【牛客网】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 HJ106 字符逆序 一、题目描述 二、测试用例 三、解题思路 基本思路&#xff1a;   考虑到可能会有多个空格&#xff0c;使用使用 getline 函数直接读取一行。   如果可以直接打印的…

CI/CD的演进之路

CI/CD的演进之路 一、CI/CD的成长演变 早期起源与初步实践&#xff1a;CI/CD的概念可以追溯到软件开发的早期阶段&#xff0c;但真正开始受到关注是在敏捷开发方法兴起之后。在传统的瀑布模型开发模式下&#xff0c;软件开发周期长、发布频率低&#xff0c;更新往往需要数月甚…

制作一款打飞机游戏55:扩散

子弹模式 ‌疯狂的子弹地狱‌&#xff1a; 嘿&#xff0c;伙计们&#xff0c;今天我们要创造一些令人印象深刻的子弹模式。这就是所谓的“子弹地狱”&#xff01; ‌问题与挑战‌&#xff1a; 在之前的开发中&#xff0c;我们遇到了一些问题。特别是关于如何处理子弹的角度问题…

Vortex GPGPU的github流程跑通与功能模块波形探索(三)

文章目录 前言一、./build/ci下的文件结构二、基于驱动进行仿真过程牵扯的文件2.1 blackbox.sh文件2.2 demo文件2.3 额外牵扯到的ramulator2.3.1 ramulator简单介绍2.3.2 ramulator使用方法2.3.3 ramulator的输出2.3.4 ramulator的复现2.3.4.1 调试与验证&#xff08;第 4.1 节…

公有云AWS基础架构与核心服务:从概念到实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 (初学者技术专栏) 一、基础概念 定义:AWS(Amazon Web Services)是亚马逊提供的云计算服务,包含计算、存储、网络、数据库等核心能力,通过全球数据中心为用户提供灵活…

wsl2 不能联网

wsl2 安装后用 wifi 共享是能联网&#xff0c;问题出在公司网络限制 wsl2 IP 访问网络&#xff0c;但是主机可以上网。 解决办法&#xff0c;在主机用 nginx 设置代理&#xff0c;可能需要开端口权限 server {listen 9000;server_name localhost;location /ubuntu/ {#…

HarmonyOS鸿蒙应用规格开发指南

在鸿蒙生态系统中&#xff0c;应用规格是确保应用符合系统要求的基础。本文将深入探讨鸿蒙应用的规格开发实践&#xff0c;帮助开发者打造符合规范的应用。 应用包结构规范 1. 基本配置要求 包结构规范 符合规范的应用包结构正确的HAP配置文件完整的应用信息 示例配置&…

异步日志分析:MongoDB与FastAPI的高效存储揭秘

title: 异步日志分析:MongoDB与FastAPI的高效存储揭秘 date: 2025/05/22 17:04:56 updated: 2025/05/22 17:04:56 author: cmdragon excerpt: MongoDB与FastAPI集成构建日志分析系统,通过Motor驱动实现异步操作,提升数据处理效率。使用Pydantic进行数据验证,配置环境变量…

[原理理解] 超分使用到的RAM模型和LLAVA模型

文章目录 前述RAM 模型介绍LLAVA 模型介绍 前述 最近在研究基于diffusion的超分模型&#xff0c;发现基本都文本编码的时候都需要用到RAM模型或者LLAVA模型&#xff0c;两个有什么区别呢&#xff1f; RAM 模型介绍 RAM&#xff08;Recognize Anything Model&#xff09; 是用…

基于 SpringBoot + Vue 的海滨体育馆管理系统设计与实现

一、项目概述 本项目是一套基于SpringBoot Vue技术栈开发的海滨体育馆管理系统&#xff0c;旨在帮助管理者更高效地管理体育馆的各项资源和活动&#xff0c;同时也为学生提供方便的借还器材、预约活动等功能。系统采用了前后端分离的架构&#xff0c;后端使用Spring Boot框架…

【时时三省】(C语言基础)对被调用函数的声明和函数原型

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 在一个函数中调用另一个函数&#xff08;即被调用函数&#xff09;需要具备如下条件 ( 1 )首先被调用的函数必须是已经定义的函数(是库函数或用户自己定义的函数)&#xff0c;但仅有这一条件…

微软宣布的五大重要事项|AI日报0520

微软宣布的五大重要事项 在 Build 大会上&#xff0c;微软向大家展示了微软如何构建开放的智能体网络。它正在重塑技术栈的每一层&#xff0c;微软的目标是帮助每一位开发者构建能够赋能世界各地的人们和组织的应用与智能体。消息来源 详细了解 以下是微软宣布的五大重要事项…

三、【数据建模篇】:用 Django Models 构建测试平台核心数据

【数据建模篇】&#xff1a;用 Django Models 构建测试平台核心数据 前言我们要设计哪些核心数据&#xff1f;准备工作&#xff1a;创建 Django App开始设计数据模型 (Models)1. 通用基础模型 (可选但推荐)2. 项目模型 (Project)3. 模块模型 (Module)4. 测试用例模型 (TestCase…

centos原系统安装了Python3.7.9兼用在安装一个python3.8

系统有个3.7.9版本的python 但是会遇到错误 usr/local/python3/lib/python3.7/site-packages/urllib3/connectionpool.py:1050: InsecureRequestWarning: Unverified HTTPS request is being made to host ‘www.xxx.com’. Adding certificate verification is strongly advi…

道可云人工智能每日资讯|浙江省人民政府印发《关于支持人工智能创新发展的若干措施》

道可云元宇宙每日简报&#xff08;2025年5月21日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 浙江省人民政府印发《关于支持人工智能创新发展的若干措施》 为抢占人工智能发展制高点&#xff0c;打造全球人工智能创新发展高地&#xff0c;浙江省人民政府于近日…

OpenGL ES 基本基本使用、绘制基本2D图形

OpenGL ES 绘制基础图形 OpenGL ES基本概念 OpenGL ES (Embedded-System) 是专为嵌入式设备&#xff08;如手机、平板、VR 设备&#xff09;设计的图形 API&#xff0c;是 OpenGL 的轻量级版本。 &#xff5c;下面是一个Android使用 OpenGL ES的基本框架 MainActivity 设置一…

JavaScript进阶(十二)

第三部分:JavaScript进阶 目录 第三部分:JavaScript进阶 十二、深浅拷贝 12.1 浅拷贝 12.2 深拷贝 1. 通过递归实现深拷贝 2. js库lodash里面cloneDeep内部实现了深拷贝 3. 通过JSON.stringify()实现 十三、异常处理 13.1 throw抛异常 13.2 try /catch捕获异常 1…