题目描述
求任意两节点路径长度(边数)的最大值。这条路不一定经过根。
树 = 1 →(2,3), 2 →(4,5)
输出 = 3 (路径 4→2→1→3)
思路解析
复用最大深度的递归:算每个节点深度的时候,顺便算一下“穿过它的最长路径”,就是左子树深度 + 右子树深度。我们一边后序遍历算深度,一边用一个全局变量记下这个和的最大值,最后就是直径。
叶子 · 深度 1:叶子节点 4、5、3 的深度都是 1。穿过叶子的路径长度 = 0+0 = 0。
节点 2 · 左深+右深 = 2:节点 2 的左子树深度(4)是 1,右子树深度(5)是 1。穿过 2 的最长路径 = 1+1 = 2,也就是 4→2→5。更新直径 = 2。同时 depth(2) = 1 + max(1,1) = 2。
根 1 · 左深+右深 = 3:根节点 1 的左子树深度(2)是 2,右子树深度(3)是 1。穿过根的最长路径 = 2+1 = 3,也就是 4→2→1→3。更新直径 = 3,这就是答案。
这是一类树形题的通用套路:递归返回一个“能拼给父节点”的量(比如深度),同时用全局变量记录一个“在当前节点结算”的答案(比如穿过它的路径)。像最大路径和(124)、最长同值路径都是这个套路。
参考代码(Python)
Python
1self.diameter = 0
2def depth(node):
3 if not node: return 0
4 L = depth(node.left)
5 R = depth(node.right)
6 self.diameter = max(self.diameter, L + R) # 穿过它的路
7 return 1 + max(L, R) # 返回深度
8depth(root); return self.diameter复杂度分析
- 时间复杂度:O(n) —— 一次后序遍历
- 空间复杂度:O(h) —— 递归栈
套路模板
记住这个骨架:全局变量在当前节点“结算横跨路径”,返回值给父节点“向上延伸”。分清这两者,这类题就不容易出错。
Python
1self.ans = 初值
2def dfs(node):
3 if not node: return 0
4 L, R = dfs(node.left), dfs(node.right)
5 self.ans = max(self.ans, 用 L,R 在此结算) # 经过当前点的答案
6 return 能向上拼接的量(L, R, node) # 给父亲用易错点
- ❌ 返回 L+R 给父亲 → ✅ 返回 1+max(L,R)(给父亲的是深度(只能选一条边往上),不是横跨路径)
- ❌ 直径按节点数算 → ✅ 直径是边数 = L+R(深度按节点、直径按边,差一要分清)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。