路径总和指从根节点到叶子节点的唯一向下路径上所有节点值之和;必须抵达叶子节点(左右子节点均为空)才结算,中途节点无效;递归中宜传递剩余目标值(targetsum − root.val),到底层判是否为0,避免全局变量与重复求和。

什么是路径总和,sum 是从根到叶子的累加值
路径总和不是任意两点之间的和,而是严格从根节点出发、每次只能向下走、最终抵达某个叶子节点所经过的所有节点值之和。关键点在于:必须到叶子才结算,中途节点不算有效路径。比如 root->left 非空但 left->left == nullptr && left->right == nullptr,那它才是叶子;如果 left->left 存在,哪怕 left->right 为空,left 也不是叶子。
递归实现时如何传递剩余目标值 targetSum
比起维护当前路径和再与 targetSum 比较,更简洁的做法是把“还差多少”往下传。每进一层就用 targetSum - root->val 更新,到底层时判断是否为 0。这样避免额外参数或全局变量,也规避了整条路径求和的重复计算。
常见错误包括:
- 没检查
root == nullptr就直接访问root->val,导致段错误 - 只判断
root->val == targetSum,却忽略必须是叶子节点这个条件 - 递归调用时仍传原始
targetSum,而非更新后的差值
正确写法示例(核心逻辑):
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) return false;
if (!root->left && !root->right)
return targetSum == root->val;
return hasPathSum(root->left, targetSum - root->val) ||
hasPathSum(root->right, targetSum - root->val);
}
需要返回所有路径时,vector<vector>></vector> 怎么安全填充
此时不能只判真假,得记录每条合法路径。用一个临时 path 向量在递归中增删节点,到达叶子且和匹配时,把当前 path 拷贝进结果 res。注意:回溯时必须 pop_back(),否则上层递归会看到残留值。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
易错点:
- 在进入递归前 push,但忘了在两个分支后都 pop —— 导致右子树路径混入左子树的节点
- 拷贝
path时用了指针或引用,结果所有路径指向同一内存 - 初始调用没清空
res和path,多次调用结果叠加
非递归写法用栈时,为什么必须同时存节点和当前和
迭代方式无法自然回退,所以栈里不能只压 TreeNode*。你得存一对信息:pair<treenode int></treenode> 或自定义结构体,其中 int 表示从根到该节点(含)的累计和。否则,弹出节点时无法知道走到这儿已经加了多少。
性能影响:相比递归,迭代略省内存(无函数调用栈开销),但代码更冗长;若树极深,递归可能栈溢出,这时迭代 + 显式栈更稳。不过 STL stack 的节点对象拷贝成本略高,生产环境可考虑用 stack<tuple int>></tuple> 或指针+值组合降低开销。
真正容易被忽略的是:迭代中判断叶子节点的方式和递归完全一致——仍要检查 node->left == nullptr && node->right == nullptr,不是看栈是否只剩一个元素。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










