leetcode 129题要求计算根到叶路径构成的数字之和:每条路径按位拼接(如1→2→3→123),仅叶节点贡献数值;递归需用值传递或显式回溯避免路径污染,状态更新为curr×10+node→val,空树返回0,时间复杂度o(n)。

如何用递归遍历并收集所有根到叶子路径
核心是边遍历边维护当前路径,遇到叶子节点就保存一份拷贝。关键不是“存路径”,而是避免引用或指针导致的路径污染——很多人用 vector<int>&</int> 传参,结果所有路径都变成最后一条。
- 必须用值传递或显式拷贝:每次递归调用前
path.push_back(root->val),回溯时path.pop_back() - 叶子判定条件是
!root->left && !root->right,不能只判!root - 空树时直接返回空结果,别让
root为nullptr还继续递归 - 示例片段:
void dfs(TreeNode* root, vector<int> path, vector<vector>>& res) {<br> if (!root) return;<br> path.push_back(root->val);<br> if (!root->left && !root->right) {<br> res.push_back(path);<br> return;<br> }<br> dfs(root->left, path, res);<br> dfs(root->right, path, res);<br>}</vector></int>
怎么把每条路径转成整数并累加(如 1→2→3 → 123)
这不是简单求和,而是按位拼接:每向下一层,当前值要乘 10 再加子节点值。容易错在初始化和进位逻辑——有人从根开始用 sum = sum * 10 + root->val,但没处理单节点树(比如只有 5,应得 5,不是 0)。
- 递归参数建议用
long long curr防止溢出(路径长 > 10 位时int不够) - 进入子节点前更新:
int next = curr * 10 + root->val,叶子处才加到总和 - 不要在非叶子节点提前累加;也不要在进入空子树时加值
- 示例:
void dfs_sum(TreeNode* root, long long curr, int& total) {<br> if (!root) return;<br> long long next = curr * 10 + root->val;<br> if (!root->left && !root->right) {<br> total += next;<br> return;<br> }<br> dfs_sum(root->left, next, total);<br> dfs_sum(root->right, next, total);<br>}
为什么用迭代写路径收集更容易出错
栈里既要存节点,又要存对应路径状态。常见错误是复用同一个 vector 对象,或忘记在弹栈后恢复路径长度——比递归多出至少两处手动管理点。
- 若坚持迭代,推荐栈元素为
pair<treenode vector>></treenode>,每次入栈都构造新路径 - 性能上迭代不比递归快,反而因频繁拷贝
vector更慢 - 调试困难:路径和节点不同步时,很难定位是哪一层压栈错了
- 除非明确要求无递归(如栈空间受限),否则递归更稳
路径数字和 vs 路径节点和:别混淆两种“和”
题目说“所有路径和汇总计算”,但没明确是拼成数字再加(如 1→2→3 = 123),还是单纯节点值相加(1+2+3=6)。这两种语义完全不同,输入样例稍变结果就差十倍以上。
- 确认题意优先级高于写代码:先看输入输出示例,或问清是否含“视为数字”“连接成整数”等关键词
-
1->2->3的节点和恒为 6;数字和取决于位权,1->2->3是 123,1->20->3却非法(节点值通常非负个位数,但规范没限定) - LeetCode 129 题明确是数字和;而面试中若只说“路径和”,大概率指节点值和 —— 别默认按数字拼接
路径深度影响数字和的位数权重,而节点和不受结构影响;前者对叶子位置敏感,后者只关心值本身。实际写之前,务必确认输入约束和期望输出格式。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











