二叉树题解——二叉树的直径【LeetCode】

543. 二叉树的直径

一、算法逻辑(逐步通顺讲解每一步思路)

🎯 问题目标:

求二叉树中任意两个节点之间的最长路径(以边数计算)。


✅ 1️⃣ 初始化变量

  • ans 用于记录目前遍历过程中的最大直径(最长路径上的边数);

  • 与上一版本不同:本实现中,返回的深度以“边数”定义,而不是“节点数”

    • 即:空节点深度为 -1,叶子节点深度为 0。


✅ 2️⃣ 定义递归函数 depth(node)

目标:返回当前 node 为根节点的最大深度(边数表示)。

处理流程如下:

✅ 递归基:
  • 如果 nodeNone,说明是空节点,返回 -1。

✅ 正常递归:
  • 递归获取左右子树的深度,并在返回值上 +1,表示当前节点比子树多一层边:

✅ 直径更新:
  • 每个节点可能作为一条最长路径的“中心节点”,该路径长度为 L + R(左右边之和);

  • 用这个值更新最大值 ans

✅ 返回当前节点的最大深度(左右中更大的那一个):

✅ 3️⃣ 主调用逻辑

  • 从根节点开始深度遍历;

  • 递归完成后,ans 中即保存了整棵树的最大直径(边数形式,无需再减 1);

  • 最终返回 ans

二、核心点总结

这段实现与传统写法不同之处在于:

把“深度”定义为边数而不是节点数,从而避免最后再手动减 1 的步骤,计算更直接。

  • 使用 nonlocal ans 来更新封闭作用域内的变量;

  • 所有的直径判断都在递归过程中逐层进行更新;

  • 核心仍是:后序遍历,自底向上构建子树信息并合并更新全局答案。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        ans = 0
        def depth(node: Optional[TreeNode]) -> int:
            if node is None:
                return -1

            L = depth(node.left)+1
            R = depth(node.right)+1
            nonlocal ans

            ans = max(ans, L+R)
            return max(L, R)

        depth(root)
        return ans

三、时间复杂度分析

  • 每个节点只访问一次;

  • 每次访问只做常数次操作;

时间复杂度:O(n),其中 n 为节点数。


四、空间复杂度分析

  • 空间主要来自递归调用栈;

  • 最坏情况为链状树 → O(n),最好情况为平衡树 → O(log n);

空间复杂度:O(h),其中 h 是树的高度。


✅ 总结一句话

本算法通过“将深度定义为边数”的方式,避免了最终再减 1 的步骤,依然使用后序递归 + 非局部变量更新最大直径的策略,在 O(n) 时间、O(h) 空间内求出二叉树的最大直径。该写法更贴近“边”的定义,简洁且逻辑紧凑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值