结论:该题需分离“单边最大贡献”与“双边路径拼接”逻辑,max_gain返回单侧正贡献(负则截断为0),全局最大路径和在每个节点用left_gain+root->val+right_gain实时更新。

直接说结论:这道题不能用普通 DFS 回溯模板硬套,必须拆解“路径贡献”和“路径拼接”两个逻辑,否则会漏掉 15 → 20 → 7 这类不经过根但横跨左右子树的路径。
为什么 max_gain 函数必须返回单边最大贡献
因为路径在向上回传时,父节点只能连左或右其中一支(否则就分叉了,违反路径定义)。所以 max_gain 的职责不是算完整路径,而是告诉父节点:“如果把我当跳板,往我这边走,最多能加多少”。
- 若左子树贡献是 -5,右子树是 8,
max_gain就该返回node->val + 8,而不是node->val + (-5) + 8 - 负贡献必须截断——用
max(0, ...)是强制归零,不是可选项 - 返回值永远 ≤ 当前节点值 + 单侧正贡献,绝不能含两侧
全局最大值必须在每个节点处用“左+中+右”更新
真正最大的路径(比如 15→20→7)恰恰是 max_gain 不返回的东西:它需要同时接入左右子树。所以更新操作必须独立写在递归体内部,不能依赖返回值。
- 计算
node->val + left_gain + right_gain后,立刻和全局变量maxSum比较并更新 - 这个值可能比
max_gain返回的大得多(如示例中 42 > 35) - 不能只在叶子或根节点更新——中间任意节点都可能是路径顶点
C++ 实现里最容易错的三处细节
这些地方一错,测试用例 [-10,9,20,null,null,15,7] 就过不了:
立即学习“C++免费学习笔记(深入)”;
-
maxSum初始值不能设为 0,得用INT_MIN——节点全为负时(如 [-3,-2,-1]),最大路径和就是 -1 - 空节点返回 0 是安全的,但别漏掉
if (!root) return 0;,否则访问root->left会崩溃 -
left_gain和right_gain必须先各自max(0, ...)再参与求和,顺序不能反;否则负值会被错误累加
核心复杂点始终只有一个:你手里有两个数(左贡献、右贡献),但只能把其中一个喂给父节点,却必须用两个一起算当前层的全局最优。这个割裂感,是所有初学者卡住的地方。


















