maxPathSum不能直接返回子树最大路径和,因为路径可跨左右子树“拐弯”,而递归只能向上贡献一条单向路径;需拆分为单向可上传路径和(用于父节点拼接)与以当前节点为顶点的完整路径和(更新全局最大值),并用max(0, ...)剪去负收益子路径。

为什么maxPathSum不能直接返回子树最大路径和?
因为路径在二叉树中可以“拐弯”——从左子树经根到右子树,但递归函数每次只能向上贡献一条单向路径(根到叶),否则会形成分叉,违反路径定义。所以必须拆成两个逻辑:当前节点能向上提供的最大单向路径和(用于父节点拼接),以及以当前节点为最高点的完整路径和(可能成为全局最大值)。
常见错误是写成一个返回值,比如只返回max(left, right) + root->val,这样漏掉了跨左右子树的路径,也丢失了更新全局最大值的机会。
- 递归函数应返回
root->val + max(0, max(left_gain, right_gain)),即单向可上传的收益(负收益截断为0) - 同时用
root->val + max(0, left_gain) + max(0, right_gain)更新全局最大值 - 节点值可能为负,所以必须允许路径只含单个节点(即不加任何负子路径)
maxPathSum递归函数里为什么要用max(0, ...)?
因为路径一旦加入负收益的子路径,就会拉低总和;而题目要求的是“最大路径和”,不是“最长路径”。只要子路径和为负,就不如从当前节点重新开始——相当于把那部分剪掉。
例如节点值为10,左子树最大单向和为-5,右子树为-2,那么最优路径就是仅10本身,而不是10 + (-5) + (-2) = 3。
立即学习“C++免费学习笔记(深入)”;
-
left_gain和right_gain是子树能提供的最大单向收益,可能为负 - 传给父节点时,若为负就取0,表示“不连下去”,等价于路径在此终止
- 但计算经过当前节点的完整路径时,左右都可独立决定是否接入(所以各自用
max(0, ...))
如何避免重复计算和全局变量误用?
多数实现依赖一个引用或类成员变量记录全局最大值,这是合理且高效的。但容易出错的地方在于:初始化值设为INT_MIN不够安全——如果所有节点都是INT_MIN,加法可能溢出;更稳妥的是初始化为首个访问节点的值,或直接用root->val起步。
另一个坑是递归中忘记处理空节点:空节点应返回0(不是INT_MIN),否则max(0, left_gain)失效,且会导致错误累加。
- 空节点返回
0,不是INT_MIN或-1 - 全局最大值变量初始设为
root->val,或在首次非空节点访问时赋值 - 不要在递归内多次调用同一子树结果(如反复算
left_gain),存入局部变量复用
C++代码中std::max嵌套和括号容易写错吗?
非常容易。比如std::max(a + b, c + d)没问题,但std::max(a + std::max(b, c), d)这类多层嵌套,漏括号或错位会导致语义完全改变。尤其当混用max(0, left_gain)时,少一层括号就变成max(0, left_gain + right_gain),逻辑全错。
建议把中间量全部命名,既防错也助调试:
int left_gain = max(0, maxPathDown(root->left)); int right_gain = max(0, maxPathDown(root->right)); int price_newpath = root->val + left_gain + right_gain; max_sum = max(max_sum, price_newpath); return root->val + max(left_gain, right_gain);
路径和计算中没有隐藏状态,所有分支都显式可控——复杂点不在算法,而在边界条件和表达式精度。稍一松懈,max括号错一位,结果就离谱。


















