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

LeetCode 404.左叶子之和的递归求解:终止条件与递归逻辑的深度剖析

一、题目解析:左叶子的定义与递归求解思路

题目描述

LeetCode 404. 左叶子之和要求计算二叉树中所有左叶子节点的值之和。左叶子的严格定义是:如果一个节点是其父节点的左子节点,并且它本身没有左右子节点,则称为左叶子

关键要点拆解

  1. 左叶子的双重条件
    • 必须是父节点的左子节点;
    • 自身必须是叶子节点(左右子节点均为空)。
  2. 递归求解核心
    • 后序遍历思想:先递归处理子树,再处理当前节点;
    • 状态传递:通过递归返回值传递子树中的左叶子和;
    • 条件判断:在递归返回后判断当前节点的左子节点是否为左叶子。

示例说明

对于二叉树:

    3/ \9  20/  \15   7

左叶子为9和15,和为24。其中:

  • 9是3的左子节点且为叶子节点;
  • 15是20的左子节点且为叶子节点。

二、递归算法的核心要素:终止与递归条件

完整代码

/*** 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 {public int sumOfLeftLeaves(TreeNode root) {if (root == null) return 0;if (root.left == null && root.right == null) {return 0;}int leftSum = sumOfLeftLeaves(root.left);if (root.left != null && root.left.left == null && root.left.right == null) {leftSum = root.left.val;}int rightSum = sumOfLeftLeaves(root.right);return leftSum + rightSum;}
}

核心要素一:终止条件设计

1. 空节点终止(base case 1)
if (root == null) return 0;
  • 逻辑:空树中没有左叶子,直接返回0。
  • 作用:避免空指针异常,作为递归的最底层返回值。
2. 叶子节点终止(base case 2)
if (root.left == null && root.right == null) {return 0;
}
  • 逻辑:叶子节点本身不是左叶子(左叶子需要有父节点),返回0。
  • 误区说明:有人可能认为叶子节点应返回自身值,但左叶子的定义依赖父节点,单独的叶子节点(如根节点)不符合左叶子条件。

核心要素二:递归条件设计

1. 左子树递归与左叶子判断
int leftSum = sumOfLeftLeaves(root.left);
if (root.left != null && root.left.left == null && root.left.right == null) {leftSum = root.left.val;
}
  • 先递归后判断的原因
    1. 递归调用sumOfLeftLeaves(root.left)先获取左子树中的左叶子和;
    2. 递归返回后,当前节点已知道左子节点的状态(是否为叶子),此时判断root.left是否为左叶子;
    3. root.left是左叶子,则用其值覆盖递归返回的左子树和(因为左子树和中不包含当前节点的左叶子,需单独累加)。
2. 右子树递归
int rightSum = sumOfLeftLeaves(root.right);
  • 逻辑:递归计算右子树中的左叶子和,右子树的左叶子判断在右子树的递归过程中完成。

三、递归流程深度解析:为什么先递归再赋值?

1. 递归调用与状态传递

递归调用链
sumOfLeftLeaves(root)↓
sumOfLeftLeaves(root.left)  // 先处理左子树↓
sumOfLeftLeaves(root.left.left)  // 递归到左子树的左子树↓
...(直到叶子节点,返回0)
  • 状态传递:递归返回值从底层叶子节点向上传递,每层处理当前节点的左叶子判断。

2. 左叶子赋值的时机分析

错误顺序假设(先判断后递归)
if (root.left是左叶子) {leftSum = root.left.val;
} else {leftSum = sumOfLeftLeaves(root.left);
}
  • 问题:若先判断再递归,会导致:
    1. 无法获取左子树内部的左叶子和;
    2. root.left不是左叶子,其内部可能还有左叶子,需递归计算。
正确顺序(先递归后判断)
leftSum = sumOfLeftLeaves(root.left);  // 先获取左子树的左叶子和
if (root.left是左叶子) {leftSum = root.left.val;  // 覆盖为当前左叶子的值
}
  • 逻辑优势
    1. leftSum初始为左子树的左叶子和;
    2. 若当前节点的左子节点是左叶子,则用其值替换(因为左子树的和不包含当前左叶子,需单独处理);
    3. 若当前节点的左子节点不是左叶子,则leftSum保持为左子树的和,正确累加。

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

示例二叉树结构

    3/ \9  20/  \15   7

递归调用过程

  1. 根节点3的处理

    • 递归调用sumOfLeftLeaves(9)(左子树);
    • 9是叶子节点,返回0;
    • 判断9是否为左叶子(是),leftSum=9
    • 递归调用sumOfLeftLeaves(20)(右子树)。
  2. 节点20的处理

    • 递归调用sumOfLeftLeaves(15)(左子树);
    • 15是叶子节点,返回0;
    • 判断15是否为左叶子(是),leftSum=15
    • 递归调用sumOfLeftLeaves(7)(右子树);
    • 7是叶子节点,返回0;
    • rightSum=0
    • 返回15+0=15
  3. 根节点3的最终计算

    • leftSum=9rightSum=15
    • 返回9+15=24

五、递归算法的复杂度分析与优化思考

1. 时间复杂度

  • O(n):每个节点仅访问一次,n为节点数。
  • 原因:递归过程中每个节点被访问一次,无重复计算。

2. 空间复杂度

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

3. 递归与迭代的对比

方法优点缺点
递归代码简洁,逻辑直观可能栈溢出
迭代空间可控,适合大数据代码复杂,需手动维护栈

4. 优化建议

  • 尾递归优化:Java不支持尾递归优化,但可通过改写递归为迭代避免栈溢出;
  • 剪枝优化:若已知某子树无左叶子,可提前返回0,减少递归深度。

六、总结:递归算法的设计哲学

1. 终止条件的设计原则

  • 最小子问题:明确最底层的返回值(空树、叶子节点返回0);
  • 无重复判断:终止条件需覆盖所有无需继续递归的情况。

2. 递归条件的核心思想

  • 分治思想:将问题分解为左子树和右子树的子问题;
  • 状态传递:通过返回值传递子问题的解,在父问题中合并;
  • 延迟判断:先递归获取子树状态,再根据子树状态处理当前节点。

3. 左叶子判断的关键

  • 依赖关系:左叶子的判断依赖父节点,因此必须在父节点的递归层处理;
  • 时机选择:在获取子树的左叶子和之后,判断当前节点的左子节点是否为左叶子,确保不遗漏也不重复。

这种递归解法充分体现了“自顶向下,先递归后判断”的设计思想,通过递归的天然分层特性,将左叶子的判断分散到各层处理,既保证了逻辑的清晰性,又实现了问题的高效求解。理解这种递归设计模式,对解决类似的树结构问题(如子树和、深度计算等)具有重要的借鉴意义。

相关文章:

LeetCode 404.左叶子之和的递归求解:终止条件与递归逻辑的深度剖析

一、题目解析:左叶子的定义与递归求解思路 题目描述 LeetCode 404. 左叶子之和要求计算二叉树中所有左叶子节点的值之和。左叶子的严格定义是:如果一个节点是其父节点的左子节点,并且它本身没有左右子节点,则称为左叶子。 关键…...

蓝桥杯5130 健身

问题描述 小蓝要去健身,他可以在接下来的 1∼n 天中选择一些日子去健身。 他有 m 个健身计划,对于第 i 个健身计划,需要连续的 天,如果成功完成,可以获得健身增益 si​ ,如果中断,得不到任何…...

电商虚拟户:重构资金管理逻辑,解锁高效归集与智能分账新范式

一、电商虚拟户的底层架构与核心价值 在数字经济浪潮下,电商交易的复杂性与日俱增,传统账户体系已难以满足平台企业对资金管理的精细化需求。电商虚拟户作为基于银行或持牌支付机构账户体系的创新解决方案,通过构建“主账户子账户”的虚拟账户…...

腾讯2025年校招笔试真题手撕(二)

一、题目 最近以比特币为代表的数字货币市场非常动荡,聪明的小明打算用马尔科夫链来建模股市。如图所示,该模型有三种状态:“行情稳定”,“行情大跌”以及“行情大涨”。每一个状态都以一定的概率转化到下一个状态。比如&#xf…...

DeepSeek快速搭建个人网页

一、环境准备 注册DeepSeek账号(https://www.deepseek.com/)安装VSCode插件:DeepSeek Coder准备基础开发环境:# 推荐使用Node.js环境 npm install -g live-server二、三步搭建基础框架 步骤1:生成基础模板 在DeepSeek对话框输入: 生成一个响应式个人网页的HTML模板,包…...

安装完dockers后就无法联网了,执行sudo nmcli con up Company-WiFi,一直在加载中

Docker服务状态检查 执行 systemctl status docker 确认服务是否正常 若未运行,使用 sudo systemctl start docker && sudo systemctl enable docker 网络配置冲突 Docker会创建docker0虚拟网桥,可能与宿主机网络冲突 检查路由表 ip route sho…...

【深度学习新浪潮】2025年谷歌I/O开发者大会keynote观察

1. 2025年谷歌I/O开发者大会keynote重点信息 本次Google I/O大会的核心策略是降低AI使用门槛与加速开发者创新,通过端侧模型(Gemini Nano)、云端工具(Vertex AI)和基础设施(TPU)的全链路优化,进一步巩固其在生成式AI领域的领先地位。同时,高价订阅服务和企业级安全功…...

小球弹弹弹

一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。求它在第十次落地时,共经过多少米?第十次反弹多高? 从第一次弹起到第二次落地前经过的路程为前一次弹起最高高度的一半乘以2,加上前面经过…...

案例分享——福建洋柄水库大桥智慧桥梁安全监测

项目背景 洋柄水库桥位于社马路(社店至马坪段)上,桥梁全长285m,桥梁中心桩号K15082跨径组合为 14x20m,全桥宽:33.8m,分左右双幅:上部结构采用空心板梁:桥采用柱式墩。 通过对桥梁结构长时间的定期观测,掌握桥梁在混凝…...

鸿蒙操作系统架构:构建全场景智慧生态的分布式操作系统

鸿蒙操作系统(HarmonyOS)是华为推出的面向全场景的分布式操作系统,旨在为智能手机、智能家居、智能穿戴、车机等多种设备提供统一的操作系统平台。鸿蒙架构的核心设计理念是“一次开发,多端部署”,通过分布式技术实现设备间的无缝协同。本文将深入探讨鸿蒙的分层架构、分布…...

NBA足球赛事直播源码体育直播M35模板赛事源码

源码名称:NBA足球赛事直播源码体育直播M35模板赛事源码 开发环境:帝国cms7.5 空间支持:phpmysql 带软件采集,可以挂着自动采集发布,无需人工操作! 演示地址:https://www.52muban.com/shop/184…...

自动化测试报告工具

自动化测试报告工具大全与实战指南 📊🔥 在自动化测试流程中,测试用例的执行只是第一步,而测试报告的生成与可视化则是闭环的重要一环。无论是个人项目还是团队协作,高质量的测试报告都能帮助我们快速定位问题、衡量测…...

Elasticsearch 实战面试题,每个题目都会单独解析

Elasticsearch 在 Java 中最常用的客户端是什么?如何初始化一个 RestHighLevelClient?如何用 Spring Boot 快速集成 Elasticsearch?Spring Data Elasticsearch 如何定义实体类与索引的映射? ES的倒排索引和正排索引的区别及适用场…...

python 中 SchedulerManager 使用踩坑

问题: 服务中我写了多个定时任务,如下: 发现到了定时时间,下面的任务就是不执行,,最后一个任务一个任务注释掉来测,发现了问题, self.scheduler_manager.add_cron_job(SearchQualit…...

Python后端框架新星Robyn:性能与开发体验的双重革命

引言:Python后端框架的进化之路 在Web开发领域,Python生态长期被Flask、Django等经典框架主导。随着异步编程需求的增长和高并发场景的普及,开发者对框架性能提出了更高要求。2023年,一款名为Robyn的新型Web框架横空出世&#xf…...

人工智能解析:技术革命下的认知重构

当生成式AI能够自主创作内容、设计方案甚至编写代码时,我们面对的不仅是工具革新,更是一场关于智能本质的认知革命。人工智能解析的核心,在于理解技术如何重塑人类解决问题和创造价值的底层逻辑——这种思维方式的转变,正成为数字…...

【Linux】基础开发工具

文章目录 一、软件包管理器1. Linux下安装软件补充知识1:操作系统的生态补充知识2:我的云服务器是怎么知道去哪找软件包的呢? 2. 查看软件包3. 安装软件4. 卸载软件5. 安装源 二、编辑器Vim1. 命令模式 三、编译器gcc / g1. 程序编译流程补充…...

OpenCV计算机视觉实战(7)——色彩空间详解

OpenCV计算机视觉实战(7)——色彩空间详解 0. 前言1. RGB/BGR 色彩空间2. HSV / Lab 色彩空间3. 颜色直方图分析与可视化小结系列链接 0. 前言 本文深入探讨了三种常见色彩空间:RGB/BGR、HSV 与 CIELAB,并介绍了 OpenCV 中色彩空…...

体育直播网站如何实现实时数据

⚽ 你是否曾好奇: 当你在看足球直播时,进球瞬间比分立刻刷新;篮球比赛中,球员数据实时跳动……这些毫秒级的赛事数据,究竟是如何"飞"到你手机上的? 今天,我们就来扒一扒体育直播网站…...

【AI模型学习】上/下采样

文章目录 分割中的上/下采样下采样SegFormer和PVT(使用卷积)Swin-Unet(使用 Patch Merging) 上采样SegFormer(interpolate)Swin-Unet(Patch Expanding)逐级interpolate的方式反卷的方…...

Unity Shader入门(更新中)

参考书籍:UnityShader入门精要(冯乐乐著) 参考视频:Bilibili《Unity Shader 入门精要》 写在前面:前置知识需要一些计算机组成原理、线性代数、Unity的基础 这篇记录一些学历过程中的理解和笔记(更新中&…...

嵌入式学习的第二十六天-系统编程-文件IO+目录

一、文件IO相关函数 1.read/write cp #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include<unistd.h> #include<string.h>int main(int argc, char **argv) {if(argc<3){fprintf(stderr, …...

珠宝课程小程序源码介绍

这款珠宝课程小程序源码&#xff0c;基于ThinkPHPFastAdminUniApp开发&#xff0c;功能丰富且实用。ThinkPHP提供稳定高效的后台服务&#xff0c;保障数据安全与处理速度&#xff1b;FastAdmin助力快速搭建管理后台&#xff0c;提升开发效率&#xff1b;UniApp则让小程序能多端…...

KNN模型思想与实现

KNN算法简介 核心思想&#xff1a;通过样本在特征空间中k个最相似样本的多数类别来决定其类别归属。"附近的邻居确定你的属性"是核心逻辑 决策依据&#xff1a;采用"多数表决"原则&#xff0c;即统计k个最近邻样本中出现次数最多的类别 样本相似性度量 …...

【信息系统项目管理师】第15章:项目风险管理 - 55个经典题目及详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...

fscan教程1-存活主机探测与端口扫描

实验目的 本实验主要介绍fscan工具信息收集功能&#xff0c;对同一网段的主机进行存活探测以及常见服务扫描。 技能增长 通过本次实验的学习&#xff0c;了解信息收集的过程&#xff0c;掌握fscan工具主机探测和端口扫描功能。 预备知识 fscan工具有哪些作用&#xff1f; …...

蓝桥杯1447 砝码称重

问题描述 你有一架天平和 N 个砝码&#xff0c;这 N 个砝码重量依次是 W1,W2,⋅⋅⋅,WN​。 请你计算一共可以称出多少种不同的重量&#xff1f; 注意砝码可以放在天平两边。 输入格式 输入的第一行包含一个整数 N。 第二行包含 N 个整数&#xff1a;W1,W2,W3,⋅⋅⋅,WN​…...

腾讯2025年校招笔试真题手撕(三)

一、题目 今天正在进行赛车车队选拔&#xff0c;每一辆赛车都有一个不可以改变的速度。现在需要选取速度差距在10以内的车队&#xff08;车队中速度的最大值减去最小值不大于10&#xff09;&#xff0c;用于迎宾。车队的选拔按照的是人越多越好的原则&#xff0c;给出n辆车的速…...

怎样通过神经网络估计股票走向

本博文将教会你如何通过神经网络建立股票模型并对其进行未来趋势估计&#xff0c;尽管博主已通过此方法取得一定利润&#xff0c;但是建议大家不要过分相信AI。本博文仅用于代码学习&#xff0c;请大家谨慎投资。 一、通过爬虫爬取股票往年数据 在信息爆炸的当今时代&#xf…...

【RocketMQ 生产者和消费者】- 生产者启动源码-上报生产者和消费者心跳信息到 broker(3)

文章目录 1. 前言2. sendHeartbeatToAllBrokerWithLock 上报心跳信息3. prepareHeartbeatData 准备心跳数据4. sendHearbeat 发送心跳上报请求5. broker 处理心跳请求5.1 heartBeat 处理心跳包5.2 createTopicInSendMessageBackMethod 创建重传 topic5.3 registerConsumer 注册…...