543. 二叉树的直径

543. 二叉树的直径

!abstract 一句话本质 直径 = 任意节点处「左子树最深链 + 右子树最深链」的最大值,不一定经过根。把每个节点都当一次"拐点"算一遍取全局最大。
!quote 链接

题目

给定二叉树根 root,求其直径长度(任意两节点之间路径的边数最大值)。

思路(从暴力到最优)

暴力想法:枚举所有节点对,跑 LCA 算距离。O(n²) 起步,太慢。

关键观察:任意一条最长路径,一定存在一个"最高点"(路径上离根最近的节点,记为拐点)。这条路径长度 = 拐点的「左子树高度」+「右子树高度」。

所以:对每个节点都算一次"以它为拐点时的路径长度" = 左深度 + 右深度,取全局最大即为直径。

DFS 设计

  • 递归函数返回值:以当前节点为端点、向下延伸到叶子的最长链长度(边数)。
  • 递归过程中副作用:用当前节点的 lLen + rLen 更新全局 ans

关键卡点

!warning 我当时卡在这

  • 直径不一定经过根! 完全可能藏在某个子树内部(左子树某条链最长 + 右子树某条链最长,拐点在子树里)。所以 ans 必须在每个节点都更新一次,而不是只在根处算一次。
  • 返回值和 ans 是两回事:返回值是"向上交给父节点的那条最长链"(要 +1 算上到父的边);ans 更新的是"经过当前节点的路径长度"(不往上走,不加 1)。+1 的 1 代表"当前节点到父节点的那条边"。
  • 单节点树直径是 0 :路径长度按边数算,需要 2 个节点 1 条边才有直径。代码中 root === null 返回 0 保证叶子节点 lLen = rLen = 0,更新 ans = 0,不会算成 1。

代码

javascript 复制代码
var diameterOfBinaryTree = function(root) {
    let ans = 0;
    function dfs(root) {
        if (root === null) {
            return 0;
        }
        const lLen = dfs(root.left);
        const rLen = dfs(root.right);
        ans = Math.max(ans, lLen + rLen);
        return Math.max(lLen, rLen) + 1;
    }
    dfs(root);
    return ans;
};

复杂度

  • 时间:O(n),每个节点访问一次。
  • 空间:O(h),h 为树高,退化为链表时 O(n);平衡树 O(log n)。

一句话记忆点

!tip 下次看到类似题 求"树中任意两点的最长路径" → DFS 返回"以本节点为端点的最长链",过程中用 左深+右深 更新全局答案。ans 全局更新,返回值只管往上交

相似题 / 套用模板

  • \[0104-二叉树的最大深度]:dfs 返回 Math.max(left, right) + 1 的模板,本题在其基础上多了一个"全局 ans 更新"。
    1. 二叉树中的最大路径和:同套路,DFS 返回"以本节点为端点的最大单链和",过程用 左 + 右 + 当前 更新全局 ans。
  • 124 后续题见题单(最大路径和 )。
相关推荐
v_34836087629 小时前
Android native端 堆栈打印
android·算法
residual_fan9 小时前
【学术论文】航空发动机故障诊断智能体:基于持续对比强化学习的动态优化方法
人工智能·算法·数据挖掘·数据分析
GreenTea10 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
深圳满意度咨询11 小时前
医院满意度数字化测评系统:从数据采集到智能决策的技术实践
算法
xiangyun6112 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun6112 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
302wanger13 小时前
推荐下我的两个AI信息源
算法
索尔~古德曼13 小时前
CF——错题的集合
算法
SL_staff14 小时前
JVS-Logic:从页面配置工具到企业级业务逻辑中枢的技术演进
java·算法·全栈
陌シ未央ゞ14 小时前
基于BM25算法和RRF实现的混合索引(java版)
人工智能·spring boot·后端·算法