最大路径和必须用全局变量或引用参数实时更新,因合法路径可为倒V型(左→根→右),无法通过单次递归返回值向上传递;递归函数只应返回以当前节点为端点的单臂最大和,倒V型路径和需在当前层计算并更新全局最大值。

直接说结论:最大路径和不能靠单次递归返回值“一路传上去”解决,必须用全局变量或引用参数在遍历中实时更新候选答案。
为什么maxPathSum函数不能只靠返回值求解
因为合法路径不要求经过根节点,也不要求是“从上到下”的单向链——它可能是个倒V型(左→根→右),而这种结构在父节点视角下是“分叉”的,无法作为单一返回值继续向上贡献。一旦你试图让递归函数同时返回“能向上贡献的单臂和”和“子树内已出现的最大路径和”,逻辑立刻变重,且容易在边界处漏判。
常见错误现象:maxPathSum返回值比预期小,尤其当最优路径完全落在某棵子树内部、没经过当前根时;或者代码在负数节点附近结果突变。
- 递归函数真正该返回的,只是“以当前节点为端点、向下延伸的单条路径最大和”(即单臂贡献)
- 而“左→根→右”这种完整路径和,只能在当前层算出后,立刻和全局最大值比较更新
- 若强行用
std::pair返回两个值,不仅增加解包负担,还容易在空节点处理时搞错默认值(比如把INT_MIN误用于单臂场景)
RemaxPathSum里为什么要对左右子贡献取max(0, ...)
这是为了保证“单臂贡献”始终是非负增益——如果左子树最大单臂和是-5,那不如不走左边,直接从当前节点开始新路径。这个截断操作只影响向上返回的值,不影响全局路径计算(因为倒V型路径会显式加上左右原始值)。
使用场景:树中存在大量负值节点时,该判断能避免路径被拖累;但要注意,它不适用于“必须包含所有节点”的变种题。
- 空节点返回 0,不是
INT_MIN——否则max(0, INT_MIN)还是 0,但语义混乱 -
left和right变量是截断后的值,仅用于计算ret(返回值) - 计算全局候选
lmr = root->val + left + right时,用的是截断前的原始递归结果?不,这里left和right已经是max(0, ...)结果,所以lmr天然排除了负向分支,逻辑自洽
全局变量Max更新时机与线程安全风险
更新必须放在递归体内部、左右子调用之后,且在返回前——早了拿不到子树信息,晚了就错过本轮计算。这个位置刚好对应后序遍历的“访问根”阶段。
性能影响:无额外时间开销;但如果你要把这段代码放进多线程环境(比如并行处理多棵树),Max必须改为局部引用参数,否则会相互覆盖。
- 别用类成员变量存
Max然后反复调用maxPathSum——上次残留值会影响下次 - 更推荐在主函数里定义
int Max = INT_MIN,再以引用方式传入辅助函数 - 测试时容易忽略:输入为单个负数节点(如
[-3]),此时Max必须能正确捕获这个负值,不能被max(0,...)逻辑掩盖
最易被忽略的一点:路径至少含一个节点,所以即使全树为负,答案也不能是 0;max(0, ...)只作用于子树贡献,根节点值永远参与计算——这个约束藏在lmr = root->val + left + right这行里,而不是靠初始化Max来兜底。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











