news 2026/4/16 9:07:33

543. 二叉树的直径

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
543. 二叉树的直径

543. 二叉树的直径
简单

给你一棵二叉树的根节点,返回该树的直径

二叉树的直径是指树中任意两个节点之间最长路径的长度。这条路径可能经过也可能不经过根节点root

两节点之间路径的长度由它们之间边数表示。

示例 1:

输入:root = [1,2,3,4,5] 输出:3 解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。

示例 2:

输入:root = [1,2] 输出:1

提示:

  • 树中节点数目在范围[1, 104]
  • -100 <= Node.val <= 100

📝 核心笔记:二叉树的直径 (Diameter of Binary Tree)

1. 核心思想 (一句话总结)

“每个节点都做两件事:1. 试图把左右臂展连起来挑战世界纪录;2. 挑一只长手臂伸向长官汇报。”

  • 直径不一定经过根节点:它可能完全出现在左子树或右子树内部。
  • 转化问题:直径 = 某一个节点处的(左子树最大链长 + 右子树最大链长)的最大值。
  • 我们利用后序遍历,在回溯的过程中,算出以当前节点为“拐点”的最长路径,并不断更新全局最大值。
2. 您的“边数计算”逻辑 (return -1)

这是一个非常棒的细节:

  • Null 节点:返回-1
  • 叶子节点:左 (-1) + 1 = 0,右 (-1) + 1 = 0。链长为 0。正确(叶子没边)。
  • 中间节点:假设左子树高L,右子树高R
    • lLen = L + 1(连上左边那条边)。
    • rLen = R + 1(连上右边那条边)。
    • 这种写法直接把+1分摊到了每一层递归里,非常优雅。
🔍 代码回忆清单
// 题目:LC 543. Diameter of Binary Tree class Solution { // 1. 全局变量:记录遍历过程中遇到的"最大臂展" // 类似于打擂台,谁的 (左+右) 更长,谁就当老大 private int ans; public int diameterOfBinaryTree(TreeNode root) { dfs(root); return ans; } // 返回值含义:从当前节点向下,能延伸出的【最大单边链长】(边数) private int dfs(TreeNode node) { // 2. Base Case: 巧妙的 -1 // 既然我们算的是"边数",null 节点贡献 -1, // 这样它的父节点 (叶子) 加上 1 之后刚好是 0 if (node == null) { return -1; } // 3. 后序遍历:先拿到左右的情报 int lLen = dfs(node.left) + 1; // 左边最长链 + 连接左子树的那条边 int rLen = dfs(node.right) + 1; // 右边最长链 + 连接右子树的那条边 // 4. 更新全局最大直径 (Hook) // 假设路径经过当前节点 (穿过),那长度就是 左 + 右 ans = Math.max(ans, lLen + rLen); // 5. 向上汇报 // 只能选一条最长的路继续往上延伸 (不能分叉) return Math.max(lLen, rLen); } }
⚡ 快速复习 CheckList (易错点)
  • [ ]为什么不能直接 returnlLen + rLen
    • 这是初学者最容易犯的错。
    • dfs函数的职责是“向上汇报高度”。如果返回lLen + rLen,相当于告诉父节点“我是一条分叉的线”,但路径是不能分叉的。父节点只能接你的左手右手。
    • 只有在更新全局ans时,才考虑“分叉/拐弯”的情况。
  • [ ]直径通过根节点吗?
    • 不一定。
    • 比如树的左边特别深,像个大哑铃,直径可能就在左子树内部。所以必须用全局变量ans在遍历过程中实时抓取最大值。
  • [ ]时间复杂度?
    • 每个节点遍历一次。
🖼️ 数字演练

树结构:

1 / \ 2 3 / \ 4 5
  1. Node 4 (Leaf):
    • dfs(null)returns -1.
    • lLen= -1+1=0,rLen= -1+1=0.
    • ans= max(0, 0+0) = 0.
    • Return: 0.
  1. Node 5 (Leaf):
    • Return: 0.
  1. Node 2:
    • lLen(from 4) = 0 + 1 = 1.
    • rLen(from 5) = 0 + 1 = 1.
    • ans= max(0, 1+1) =2. (路径 4-2-5)
    • Return: max(1, 1) = 1. (告诉 1 号节点,我这边最长能提供 1 条边的深度)
  1. Node 3 (Leaf):
    • Return: 0.
  1. Node 1 (Root):
    • lLen(from 2) = 1 + 1 = 2.
    • rLen(from 3) = 0 + 1 = 1.
    • ans= max(2, 2+1) =3. (路径 4-2-1-3)
    • Return: 2.

最终结果: 3。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:07:16

2025内容备份革新:Fantia媒体资源下载全攻略

2025内容备份革新&#xff1a;Fantia媒体资源下载全攻略 【免费下载链接】fantiadl Download posts and media from Fantia 项目地址: https://gitcode.com/gh_mirrors/fa/fantiadl 你是否也曾遇到心仪的创作者内容因平台限制无法保存&#xff1f;是否担心错过限时发布的…

作者头像 李华
网站建设 2026/4/13 7:41:57

Nintendo Switch平台wiliwili客户端完全指南

Nintendo Switch平台wiliwili客户端完全指南 【免费下载链接】wiliwili 专为手柄控制设计的第三方跨平台B站客户端&#xff0c;目前可以运行在PC全平台、PSVita、PS4 和 Nintendo Switch上 项目地址: https://gitcode.com/GitHub_Trending/wi/wiliwili 还在为Switch上无…

作者头像 李华
网站建设 2026/4/15 13:09:06

揭秘英雄联盟内存换肤技术:如何安全实现皮肤自定义

揭秘英雄联盟内存换肤技术&#xff1a;如何安全实现皮肤自定义 【免费下载链接】R3nzSkin Skin changer for League of Legends (LOL).Everyone is welcome to help improve it. 项目地址: https://gitcode.com/gh_mirrors/r3n/R3nzSkin 为什么传统换肤方法存在安全风险…

作者头像 李华
网站建设 2026/4/15 5:15:00

Dify文档解析吞吐量卡在12QPS?别再调workers了——底层LangChain DocumentLoader线程池死锁根源及热修复补丁(含patch文件下载链接)

第一章&#xff1a;Dify文档解析优化Dify 作为低代码 AI 应用开发平台&#xff0c;其文档解析能力直接影响 RAG&#xff08;检索增强生成&#xff09;流程的准确性与响应质量。默认解析器对 PDF、Markdown 和 Word 等格式虽具备基础支持&#xff0c;但在处理多栏排版、嵌入表格…

作者头像 李华
网站建设 2026/4/13 9:09:38

Dify插件热更新失效真相:Vite HMR在WebWorker沙箱中的3层劫持机制,以及如何绕过Dify Runtime缓存强制刷新(生产环境已验证)

第一章&#xff1a;Dify插件热更新失效的根源认知Dify 的插件系统设计为支持运行时动态加载&#xff0c;但实践中热更新常出现“修改后未生效”“重启才触发新逻辑”等现象。其根本原因并非配置遗漏或缓存未清除&#xff0c;而是源于插件模块加载机制与 Python 解释器导入缓存&…

作者头像 李华
网站建设 2026/4/8 8:34:08

时间操控技术:RunAsDate提升软件测试效率的全方案

时间操控技术&#xff1a;RunAsDate提升软件测试效率的全方案 【免费下载链接】RunAsDate 类型于 RunAsDate 软件&#xff0c;C#实现代码 项目地址: https://gitcode.com/malaohu/RunAsDate RunAsDate作为一款专业的时间模拟工具&#xff0c;通过为目标进程创建独立的时…

作者头像 李华