递归DFS遍历二叉树收集根到叶路径,需维护当前路径并及时回溯;到达叶子节点时将路径加入结果,退出递归前必须pop_back以避免污染;空树需特判,路径求和用std::accumulate。

如何用递归遍历收集所有根到叶路径
直接用深度优先搜索(DFS)递归是最自然的做法,关键在于维护当前路径和及时回溯。每次进入节点就把 val 加入临时路径,到达叶子时把整条路径复制进结果容器;退出当前递归层前必须从路径中移除该节点值——否则上层调用看到的是污染后的路径。
常见错误是忘记回溯,导致后续分支路径混入前面节点的值;或者在非叶子节点就提前 push 到结果里。
- 使用
vector<int>存当前路径,vector<vector<int>>存所有路径 - 递归参数:当前节点指针、引用传递的路径 vector、结果 vector 引用
- 叶子判断条件是
!root->left && !root->right,不是!root - 空树输入要单独处理,否则递归入口可能崩溃
路径总和汇总只需累加每条路径的元素和
拿到所有路径后,对每个 vector<int> 用 std::accumulate 或手动循环求和即可。不需要在 DFS 过程中同步计算总和——那样会丢失路径结构,后续没法做其他分析(比如找最长路径、最大和路径等)。
如果只关心“总和是否等于某目标值”,那可以边遍历边减目标值,到叶子时判断剩余是否为 0,节省空间;但题目明确要求“所有路径的总和汇总”,就得先存全路径再算。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
std::accumulate(path.begin(), path.end(), 0)是最简洁的求和方式 - 注意 int 溢出风险:若节点值很大或路径很长,建议用
long long累加 - 汇总结果可用
vector<int>存每条路径和,也可用单个int累加全部路径和——需确认题意中“汇总”指集合还是总量
迭代写法容易漏掉路径重建逻辑
用栈模拟递归时,不能只存节点指针,必须同时保存对应路径。常见错误是只压栈节点,导致弹出时无法还原该节点所属的完整路径。
可行做法是栈中存 pair<TreeNode*, vector<int>>,每次出栈后,若为叶子则记录路径;否则将左右子节点连同当前路径 + 自身值一起入栈。但空间开销明显高于递归(每层都拷贝 vector)。
- 避免在循环内反复调用
path.push_back()后不 pop —— 迭代里没有自动回溯 - 若改用栈存路径长度而非完整 vector,需额外维护一个长度数组,复杂度陡增
- 除非明确禁止递归或栈深度超限,否则优先选递归
LeetCode 113 题型适配要点
这题实际就是 LeetCode 113 “Path Sum II” 的变体,原题要求返回所有和等于 targetSum 的路径;而你需求是汇总所有路径的和,所以核心逻辑一致,只是结果处理不同。
注意原题测试用例包含负数节点值,所以路径和可能为负;也存在空树、单节点等边界情况,本地测试务必覆盖 nullptr 输入。
- 函数签名建议用
vector<vector<int>> binaryTreePaths(TreeNode* root)先获取路径,再另写函数汇总 - 不要在递归中用全局变量存路径或结果——多线程或连续调用时会出错
- LeetCode C++ 环境中
TreeNode定义含val、left、right,别手误写成data或key
路径重建和回溯时机是绝大多数人卡住的地方,写完务必用三节点斜树(根→左→左)单步调试,看第二条路径是否包含第一个根节点以外的冗余值。

















