后序递归需拆分返回值与全局最大值:返回以当前节点为终点的单链最大和(root->val + max(0, left, right)),同时用全局变量或引用参数维护经过任意节点的最大路径和(root->val + max(0,left) + max(0,right))。

后序递归怎么设计返回值才能兼顾路径和贡献
直接让递归函数返回「以当前节点为根的子树中,经过该节点的最大路径和」是行不通的——这会强制路径必须向下延伸两次(左右子树),但合法路径在某个节点最多只能拐一次弯。所以必须拆开:一个值用于向上贡献(只能选左或右单边,或不选),另一个隐含在全局变量里维护真正的最大路径和。
典型错误是写成 return left + right + root->val,这实际算的是「经过 root 的完整路径」,但它不能作为向上传递的值,因为父节点无法再接续。
- 递归函数返回值定义为:以当前节点为终点、向上延伸的单链最大和(即:root 本身 + max(0, 左子树贡献, 右子树贡献))
- 每次递归中,用
left + right + root->val尝试更新全局最大值(left和right是左右子树返回的单链贡献,可为负,但路径中允许不选负分支,所以实际计算前要和 0 取大) - 注意:若子树贡献为负,向上贡献时应截断,即取
max(0, child_contribution),否则拉低父节点的单链价值
为什么必须用全局变量或引用传参存答案
后序遍历天然适合汇总子树信息,但最大路径不一定经过根,可能完全落在左子树、右子树,或横跨左右+当前节点。递归返回值只能服务「向上连接」逻辑,没法同时表达「就在这里封顶」的路径。
常见错误是试图用返回值承载所有信息,比如返回 pair 或 struct,结果在父层判断时逻辑爆炸,且容易漏掉 root->val 单独成路径的情况。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 最简方案:声明一个
int max_sum = INT_MIN全局变量,每层算完cur_path = root->val + max(0, left) + max(0, right)后立刻更新它 - 更稳妥方案:通过引用参数传入,如
dfs(root, max_sum),避免全局状态污染 - 别忘了考虑单节点路径:
root->val本身可能就是最大值(当左右子树贡献全为负时)
递归终止与负值处理的边界细节
空节点返回 0 是常规做法,但这里有个关键点:它代表「不选这条分支」,不是「这条分支贡献为 0」。如果子树整体为负,我们宁愿不走它,所以用 max(0, dfs(child)) 包一层,而不是直接加。
容易踩的坑是混淆「空节点返回值」和「负子树截断逻辑」——前者是递归基础,后者是路径优化策略,两者缺一不可。
- 空节点返回
0,不是INT_MIN,否则max(0, dfs(nullptr))永远不会生效 - 每个子树返回前必须做
max(0, contribution),否则父节点叠加后路径会变短(比如 -5 + 3 = -2,但其实只选 3 更优) - 整棵树全负时,最大路径就是最大的那个叶节点值,靠
cur_path = root->val + ...这一行自然覆盖,无需额外特判
C++ 实现里要注意的类型与初始化
用 INT_MIN 初始化全局最大值很常见,但要注意:如果所有节点都是 INT_MIN,累加会溢出。不过题目一般保证节点值在 int 范围内,且路径至少含一个节点,所以安全。
另一个易错点是递归函数签名——返回类型必须是 int,不能是 long long,除非题目明确说值可能超 int;但全局变量类型要和返回值一致,否则比较时隐式转换可能出问题。
- 推荐写法:
int max_gain(TreeNode* node, int& max_sum),引用传参更清晰 - 返回语句写成
return node->val + max({0, left, right}),用max({...})避免嵌套max(0, max(left, right)) - 不要在递归里反复 new/delete 或用 map 缓存,纯 DFS 时间复杂度已是 O(n),额外开销反而拖慢
实际跑起来最常卡住的地方,是忘记对左右子树贡献值做非负截断,或者把更新全局最大值的位置错放到 return 前但没覆盖单节点情况。这两处漏掉,样例可能过,但遇到全负树或单边深树就崩。

















