因为路径在二叉树中必须是“一条线”,不能分叉,故每个节点向上仅能贡献单向路径和(leftsingle 或 rightsingle 之一),而横跨左右的路径(root→left→right)仅用于更新全局最大值,不可返回。

为什么 maxPathSum 不能直接返回左右子树最大路径和之和
因为题目定义的「路径」是任意两个节点之间的**无向、不重复节点**的连续序列,且路径可以不经过根——但关键限制是:**路径在二叉树中必须是“一条线”,不能分叉**。所以从某个节点出发,最多只能向下延伸到左或右(不能同时),否则就形成“Y”形,违反路径定义。
这意味着对每个节点 root,我们需区分两个值:
-
singlePath:以root为起点,**单向向下**(至多含左或右子树)的最大路径和(可为空,即 0),用于向上贡献给父节点 -
maxPath:当前子树内**全局最大路径和**(可能横跨左-根-右),这个值不参与递归返回,只用于更新全局答案
std::max({a, b, c}) 在路径比较中的实际用途
C++11 起支持 initializer_list 版本的 std::max,它比嵌套 std::max(a, std::max(b, c)) 更清晰,尤其适合比较三种候选路径:
- 仅左子路径:
leftSingle - 仅右子路径:
rightSingle - 仅当前节点(放弃子树,防止负数拖累):
0
所以计算向上贡献值时写成:int singlePath = root->val + std::max({0, leftSingle, rightSingle});
注意这里用 0 表示“不选任何子路径”,不是 std::max(0, ...),因为后者会强制至少选一个非负值,而 std::max({0, a, b}) 才真正表达“三者取大”,允许全为负时选 0(即放弃子树)。
处理负值节点时为什么必须初始化 maxSum = INT_MIN
如果树中所有节点都是负数(如 [-2, -1]),合法路径就是单个节点(不能为空),最大和应为 -1。若初始化为 0 或 root->val,就会漏掉更优解。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 错误写法:
int maxSum = 0;→ 对全负树返回 0(非法,路径不能为空) - 危险写法:
int maxSum = root->val;→ 未遍历前无法确定根是否最优 - 正确做法:
int maxSum = INT_MIN;,并在每层用std::max(maxSum, root->val + leftSingle + rightSingle)更新
注意:横跨路径值是 root->val + leftSingle + rightSingle,其中 leftSingle 和 rightSingle 已经是“选或不选”的结果(≥0),所以即使 root->val 是负的,只要左右足够正,仍可能构成最大路径。
递归函数为什么返回 singlePath 而不是 maxPath
因为父节点构造自己的路径时,只能接入一个子方向;它需要知道“如果我选左子树,最多能带回来多少”、“选右子树呢”,而不是“左子树内部最大路径是多少”——后者对父节点毫无用处。
- 返回值本质是:**当前节点作为路径端点时,向下能提供的最大增益**
- 该值必须 ≥0(否则不如不选),所以有
std::max(0, ...)截断 - 全局最大值靠成员变量或引用参数维护,不可靠地依赖返回值传递
典型错误是试图让递归函数同时返回两个值(如用 std::pair),徒增复杂度且易混淆职责——分离「向上贡献」和「全局更新」才是清晰解法。
最易被忽略的一点:路径不要求必须到叶子,也不要求包含根,甚至可以只有一个节点;所以每次计算横跨路径时,都要无条件更新全局最大值,哪怕 leftSingle 和 rightSingle 都是 0(此时路径就是孤立的 root)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










