因为路径可跨根节点形成“左→根→右”V字形,而递归函数只能返回以当前节点为起点的单向路径和;必须用全局变量记录所有路径最大值,递归函数仅返回max(0, max(left, right)) + root->val。

为什么 maxPathSum 不能直接返回子树最大路径和?
因为路径在二叉树中是「任意两点间不重复经过节点的连通序列」,而递归函数每次只能向上交出一条「从当前节点向下延伸的单向路径」——它必须连续、不能分叉。所以 maxPathSum 的递归函数实际承担两个职责:一是计算以当前节点为“最高点”的完整路径(左+根+右),二是返回能向上拼接的单向最大收益(max(0, 左收益) + root->val)。这两个值不能混用,否则会误把分叉路径当单链上传。
常见错误是让递归函数直接返回 left + root->val + right,结果导致父节点试图把左右子树的完整路径再拼起来,形成非法“Y型”路径。
实操建议:
- 定义递归函数语义:返回「能向上延伸的最大单向路径和」(即从当前节点出发,只往一个方向走到底)
- 全局变量或引用参数记录所有可能的「完整路径和」最大值(即
left + root->val + right) - 空节点返回 0,负收益子路径主动截断(用
max(0, ...))——因为加负数只会拉低父节点的路径和
std::max 和负数处理怎么影响路径选择?
关键在于:是否允许路径在某一层“不往下走”。比如某个子树最大单向和是 -5,那么从父节点视角,不如直接停在这儿,路径就只有父节点自己——等价于加 0。这就是为什么递归返回值要写成 root->val + max({0, left_gain, right_gain}),而不是 root->val + max(left_gain, right_gain)。
立即学习“C++免费学习笔记(深入)”;
错误现象:输入 [−3] 返回 -3 没问题;但输入 [−10, 9, 20, null, null, 15, 7],若没截断负收益,右子树 15+7=22 正确,但若左子节点是 -5,不截断就会让根节点路径变成 -10 + (-5) = -15,而实际最优是只取 -10 自身。
实操建议:
- 每个子树的
gain(贡献值)统一用max(0, dfs(child))计算,确保只传递非负增益 - 完整路径候选值仍需保留原始左右值参与计算:
current_sum = root->val + left_gain_raw + right_gain_raw,但注意这里 left_gain_raw 是未截断前的递归返回值(即你本该返回的值),不是截断后的 - 更稳妥做法:递归函数内部先算左右 raw 值,再算截断后用于返回的值,避免覆盖
如何调试路径和计算中的符号与顺序错误?
最常踩的坑是把加法顺序写反,或漏掉 root->val。例如写成 left + right 忘了加根节点,或写成 root->val + left 却把 right 当作另一分支丢弃——其实它可能构成更好的完整路径。
错误信息往往不报错,而是返回值偏小(如应为 42 却返回 15),说明某段路径被意外截断或遗漏。
实操建议:
- 在递归入口打日志:
cout val - 检查三处加法是否都含
root->val:单向返回值、完整路径候选值、以及更新全局答案时 - 手画小样例(如
[2, -1, -2])验证:最大路径应是 2(只取根),不是 2 + (-1) = 1,也不是 (-1) + 2 + (-2) = -1 —— 这靠max(0, left)截断左子树实现
C++ 实现中 INT_MIN 初始化和溢出风险怎么避?
全局答案变量若初始化为 0,遇到全负树(如 [-2,-3])就会错判为 0。必须用 INT_MIN;但要注意:INT_MIN + 负数 可能溢出,虽然本题路径和不会极端大,但安全起见,所有加法前做符号判断更稳。
不过实践中,只要确保每个子路径收益已用 max(0, ...) 截断,且根节点值本身在 int 范围内,root->val + left_gain + right_gain 就不会因负数叠加溢出——因为最多加一次 root->val 和两个非负数。
实操建议:
- 答案变量声明为
long long ans = numeric_limits<long long>::min()</long>,避免int溢出干扰逻辑 - 不要依赖
INT_MIN + x的行为,哪怕 x 很小;改用更大类型承载中间计算 - LeetCode 测试用例里有
[-2, -1]这类边界,务必用最小值初始化并单独测
真正卡住人的从来不是递归结构,而是对「路径」定义的机械套用——它既不是子树和,也不是最大深度,而是一种带约束的局部组合。每层递归都在回答两个问题:我能向上交什么?我在这一层能组出什么最好的完整路径?把这两个答案分开维护,剩下的就是小心别把它们弄混。


















