节点收益是以该节点为路径最高点时能向上贡献的最大单侧路径和,即node->val + max(0, left_gain, right_gain),用于父节点拼接单链,而非直接作为答案。

什么是“节点收益”?它和路径和到底什么关系
最大路径和问题里说的“路径”,是树中任意两个节点之间的一条无向、不重复经过节点的通路。但递归处理时,你没法直接算任意两点间路径——必须拆解到每个节点的视角。
所谓“节点收益”,就是以该节点为**路径最高点(即转折点)** 时,它能向上贡献的最大单侧路径和(含自身)。注意:这个值不是最终答案,而是供父节点计算用的中间量。它必须满足“向下最多只走左或右一棵子树”,否则向上拼接时会形成分叉,违反路径定义。
-
node->val单独成路径,收益就是它自己 - 如果
left_gain > 0,可以接上左子树最大单侧路径;否则舍弃(加负数只会拉低) - 同理判断
right_gain - 所以节点收益 =
node->val + max(0, left_gain, right_gain)
为什么不能直接返回左右子树最大路径和之和
因为递归函数要同时承担两个职责:一是为父节点提供可向上延伸的“单链收益”,二是更新全局最大路径和。若直接返回 node->val + left_gain + right_gain,虽然这可能是当前节点作为最高点时的完整路径和(即答案候选),但它无法被父节点安全使用——父节点再往上连就会形成“Y”形,不再是合法路径。
常见错误写法:return node->val + left_gain + right_gain; —— 这会导致上层误把分叉当单链,最终结果偏大或崩溃。
- 正确做法:递归函数返回值只能是单侧最大收益(用于父节点拼接)
- 而
node->val + left_gain + right_gain只用于和全局变量max_sum比较更新 - 记得初始化
max_sum为INT_MIN,否则全负数用例会出错
递归终止与负收益处理的关键细节
空节点返回 0 是标准写法,但容易忽略它的实际含义:不是“没有贡献”,而是“不拖累”。当子树最大单侧路径和为负时,父节点选择不走它,等价于加 0。
例如节点值为 -10,左子树收益 -5,右子树收益 -8,那么该节点收益 = -10 + max(0, -5, -8) = -10。此时整条路径就只有它自己,仍是合法路径。
- 所有子树收益都用
max(0, gain)截断,这是“是否采纳该分支”的开关 - 但节点自身值永远参与计算,哪怕它是负数——因为路径至少包含一个节点
- 不要在递归入口提前 return;即使
node == nullptr,也要让它自然返回 0,保持调用一致性
实战中容易漏掉的边界场景
全负数树、单节点树、链状树(只有左或只有右)、根节点本身是全局最大路径的一部分但不作为最高点——这些都会暴露逻辑漏洞。
比如输入 [-3],输出必须是 -3,不是 0;又如 [2,-1,-2],最大路径是 2 自身,不是 2→-1 这条(和为 1)。
- 测试时务必覆盖
[-2,-1](答案 -1)、[1,-2,-3](答案 1)、[5,4,null,11,2](答案 22) - 别依赖“叶子节点一定参与答案”——最大路径可能只含一个非叶节点
- 更新全局最大值的时机必须在左右子收益拿到之后、返回之前,且要包含三者组合:
node->val、node->val + left_gain、node->val + right_gain、node->val + left_gain + right_gain
最易错的是把“节点收益”和“该节点出发的最长路径”混为一谈;前者是为父服务的出口值,后者才是你要找的答案候选。盯住这个分工,递归结构就稳了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











