LeetCode 124. 二叉树中的最大路径和(Hard)
📌 题目链接
💡 解题思路
一、什么是"路径"
题目要求的是 任意节点组成的一条路径,路径满足:
- 至少包含一个节点
- 不一定经过根节点
- 节点只能经过一次
- 路径可以是:
- 左子树 → 当前节点 → 右子树
- 左子树 → 当前节点
- 当前节点 → 右子树
- 单个节点
二、核心难点
递归返回值 ≠ 全局答案
- 递归函数只能返回 "向上延伸的路径"
- 不能返回"拐弯的路径"
- 但 全局最大值 可以来自"拐弯路径"
🌳 递归设计
1️⃣ 递归函数定义
java
int dfs(TreeNode node)
含义:
返回以
node为起点,向下走(只能选一条分支)的最大路径和
2️⃣ 递归逻辑
对于当前节点 node:
java
int l = dfs(node.left); // 左子树最大贡献
int r = dfs(node.right); // 右子树最大贡献
✅ 更新全局答案
java
ans = max(ans, l + r + node.val);
这表示:
- 当前节点作为路径最高点
- 同时连接左右子树
✅ 向上返回
java
return max(max(l, r) + node.val, 0);
📌 为什么要和 0 取 max?
- 如果子树贡献为负,不如不选
- 保证路径和不会被拖垮
🧩 完整代码(Java)
java
class Solution {
private int ans;
public int maxPathSum(TreeNode root) {
ans = Integer.MIN_VALUE;
dfs(root);
return ans;
}
private int dfs(TreeNode node) {
if (node == null) return 0;
int l = dfs(node.left);
int r = dfs(node.right);
// 以当前节点为最高点的路径
ans = Math.max(ans, l + r + node.val);
// 向上返回(只能选一条分支)
return Math.max(Math.max(l, r) + node.val, 0);
}
}
⏱ 复杂度分析
| 指标 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 每个节点只访问一次 |
| 空间复杂度 | O(h) | 递归栈深度 |
- 平衡树:
O(log n) - 链状树:
O(n)
🔍 易错点总结
| 易错点 | 正确做法 |
|---|---|
| 返回左右子树之和 | ❌ 不能返回给上层 |
| 忽略负数 | ✅ 与 0 取 max |
| 忘记更新全局变量 | ✅ 必须在递归中更新 |
| 认为路径必须过根 | ❌ 任意位置均可 |
✅ 一句话总结
递归负责"向上传",全局变量负责"记录拐点";
二叉树最大路径和 = 左贡献 + 右贡献 + 当前节点。