(LeetCodeHot100)543. 二叉树的直径——diameter-of-binary-tree
(LeetCodeHot100)543. 二叉树的直径——diameter-of-binary-tree
zhangzhang543. 二叉树的直径——diameter-of-binary-tree
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
示例 1:
1 | 输入:root = [1,2,3,4,5] |
示例 2:
1 | 输入:root = [1,2] |
提示:
- 树中节点数目在范围
[1, 104]内 -100 <= Node.val <= 100
- 一看到这个题目一头雾水,之前只会求最大深度
- 这题确实会用到最大深度:
- 两个叶子结点之间路径=根节点左右儿子的深度之和
- 但是会出现这个问题:
- 所以跟之前的求最大深度不一样:要加一个ans,每次过一个结点就求最大路径(深度之和),每次就比较一次,把大的放入ans
方法:深度优先搜索
首先我们知道一条路径的长度为该路径经过的节点数减一,所以求直径(即求路径长度的最大值)等效于求路径经过节点数的最大值减一。
而任意一条路径均可以被看作由某个节点为起点,从其左儿子和右儿子向下遍历的路径拼接得到。
核心逻辑
二叉树直径 = 树中任意两节点最长路径的边数 → 等效于「最长路径的节点数 - 1」。
关键观察
任意一条最长路径,必然以某个节点为「中心」,由该节点的「左子树最深路径」和「右子树最深路径」拼接而成(即:左路径 + 中心节点 + 右路径)。
算法步骤(递归)
- 定义递归函数
depth(node):- 输入:当前节点
node - 输出:以
node为根的子树的「深度」(即从node到最远叶子的节点数) - 隐藏作用:计算以
node为中心的最长路径节点数,更新全局最大值。
- 输入:当前节点
- 递归计算:
- 若
node为null,返回深度 0(空树无节点)。 - 递归左子树,得到左子树深度
L。 - 递归右子树,得到右子树深度
R。
- 若
- 更新最长路径:
- 以当前节点为中心的路径节点数 =
L + R + 1(左路径节点数 + 右路径节点数 + 中心节点)。 - 用这个值更新全局变量
ans(记录所有节点中最大的路径节点数)。
- 以当前节点为中心的路径节点数 =
- 返回子树深度:
- 以
node为根的子树深度 =max(L, R) + 1(取左右子树较深的一个,加当前节点)。
- 以
- 最终结果:
- 直径 = 最长路径节点数(
ans) - 1(节点数转边数)。
- 直径 = 最长路径节点数(
1 | class Solution { |
复杂度分析
- 时间复杂度:O(N),其中 N 为二叉树的节点数,即遍历一棵二叉树的时间复杂度,每个结点只被访问一次。
- 空间复杂度:O(Height),其中Height 为二叉树的高度。由于递归函数在递归过程中需要为每一层递归函数分配栈空间,所以这里需要额外的空间且该空间取决于递归的深度,而递归的深度显然为二叉树的高度,并且每次递归调用的函数里又只用了常数个变量,所以所需空间复杂度为 O(Height) 。





