129. 求根节点到叶节点数字之和(Sum Root to Leaf Numbers)

频次 ★★★ · 难度 🟡 · 高频:字节

题目

给定二叉树,每个节点值 0-9。每条根到叶的路径代表一个数字(路径上节点值依次拼接),求所有路径数字之和。

示例

输入: [1,2,3]
    1
   / \
  2   3
输出: 12 + 13 = 25

输入: [4,9,0,5,1]
    4
   / \
  9   0
 / \
5   1
输出: 495 + 491 + 40 = 1026

思路

DFS 前序遍历:递归时传递从根到当前节点的前缀数字 prev = prev * 10 + root.val。到达叶节点时累加到全局和。

也可以不用全局变量,递归返回”左子树和 + 右子树和”。

代码

public int sumNumbers(TreeNode root) {
    return dfs(root, 0);
}
 
private int dfs(TreeNode node, int prev) {
    if (node == null) return 0;
    int cur = prev * 10 + node.val;
    if (node.left == null && node.right == null)
        return cur;                     // 叶节点,返回路径数字
    return dfs(node.left, cur) + dfs(node.right, cur);
}

复杂度

  • 时间:O(n) — 每个节点访问一次
  • 空间:O(height) — 递归栈深度

边界条件

  • 空树:dfs 返回 0
  • 单节点:prev * 10 + val 即为节点值本身
  • 节点值为 0:如根为 0,左子为 5,路径数字为 05 = 5(前导 0 不影响数值)

变式

易错点

  • 数字拼接用 prev * 10 + val,不是字符串拼接再 parseInt(后者效率低且违背面试希望看到的数学精度感)。
  • 返回值的累加方式:dfs(left) + dfs(right),不能只返回一边。
  • 非叶节点不参与求和(题目要求”根到叶”才算一个数字),所以求和只在叶节点进行。

面试追问

  • 如果节点值不限于 0-9 呢? 需要大数处理,用字符串拼接或 BigInteger。但面试中通常限定 0-9。
  • BFS 层序能做吗? 能——队列同时存节点和当前路径数字,层序遍历时更新。空间 O(n) 和 DFS 的 O(height) 各有优劣。
  • 如果溢出怎么办? LeetCode 原题保证结果在 int 范围内。如果题目改成不限位数,用 longBigInteger

关联题