二叉树的直径问题
字数 1013 2025-11-11 01:34:56
二叉树的直径问题
题目描述
给定一棵二叉树,你需要计算它的直径长度。二叉树的直径是指树中任意两个节点之间最长路径的长度。这条路径可能不经过根节点,但必须保证是连通两个叶节点的简单路径(即不会重复经过同一个节点)。路径长度由节点之间的边数表示。
关键点分析
- 直径可能经过根节点,也可能完全位于某棵子树中。
- 直径的长度可分解为:左子树的最大深度 + 右子树的最大深度(若路径经过当前节点)。
- 需要遍历所有节点,计算以每个节点为根的子树直径,并记录最大值。
解题思路
-
问题转化
- 对于任意节点,若其左子树深度为
L,右子树深度为R,则经过该节点的直径长度为L + R。 - 全局直径是所有节点中
L + R的最大值。
- 对于任意节点,若其左子树深度为
-
深度计算与直径更新
- 采用后序遍历(左右根),在计算节点深度的同时更新直径。
- 节点深度定义为从该节点到最远叶节点的边数(叶节点深度为0)。
-
算法步骤
- 初始化全局变量
maxDiameter记录当前最大直径。 - 递归函数
depth(node)返回以node为根的子树深度:- 若节点为空,返回深度
-1(空节点无边,深度为-1便于边数计算)。 - 递归计算左子树深度
leftDepth。 - 递归计算右子树深度
rightDepth。 - 更新
maxDiameter = max(maxDiameter, leftDepth + rightDepth + 2)(+2表示连接左右子树的边)。 - 返回当前子树深度
max(leftDepth, rightDepth) + 1。
- 若节点为空,返回深度
- 初始化全局变量
逐步示例
以二叉树为例:
1
/ \
2 3
/ \
4 5
- 节点4:深度0,左右子树深度-1,直径=0。
- 节点5:深度0,直径=0。
- 节点2:左子树深度0(节点4),右子树深度0(节点5),直径=0+0+2=2。
- 节点3:深度0,直径=0。
- 节点1:左子树深度1(节点2的深度),右子树深度0(节点3),直径=1+0+2=3。
最终直径为3(路径4→2→1→3或5→2→1→3,边数为3)。
代码实现(Python)
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.maxDiameter = 0
def depth(node):
if not node:
return -1 # 空节点深度为-1,使叶节点深度为0
leftDepth = depth(node.left)
rightDepth = depth(node.right)
# 更新直径:左深度+右深度+2条连接左右子树的边
self.maxDiameter = max(self.maxDiameter, leftDepth + rightDepth + 2)
return max(leftDepth, rightDepth) + 1 # 返回当前子树深度
depth(root)
return self.maxDiameter
复杂度分析
- 时间复杂度:O(N),每个节点被访问一次。
- 空间复杂度:O(H),递归栈空间(H为树高,最坏情况O(N))。
总结
- 核心思路:将直径问题转化为对每个节点计算“左右子树深度和”的最大值。
- 关键技巧:后序遍历同时完成深度计算与直径更新,避免重复计算。
- 边界处理:空节点深度设为-1可统一边数计算逻辑。