AlgoMaster Logo

Sum Root to Leaf Numbers

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We have a binary tree where each node holds a single digit (0-9). Every path from the root down to a leaf spells out a multi-digit number. Our job is to find the sum of all such numbers.

Take the tree [1,2,3]. The root is 1, with left child 2 and right child 3. The path 1->2 gives us the number 12 (not 1+2=3, but the concatenated digits treated as a decimal number). The path 1->3 gives us 13. The answer is 12 + 13 = 25.

The problem combines two subproblems: enumerate all root-to-leaf paths, and turn each path into a number. The first is standard tree traversal. The second comes down to one arithmetic fact: as we walk from root to leaf, each new digit shifts the previous number left by one decimal place and adds itself. If the running number so far is currentNum and the next node's value is val, the new number becomes currentNum * 10 + val. That is how we read numbers left to right, so we can build each path's number incrementally as we descend.

Key Constraints:

  • Number of nodes in [1, 1000]: The tree is never empty, so there is always at least one leaf and one path number to add. With at most 1000 nodes, a single O(n) traversal is fast enough.
  • 0 <= Node.val <= 9: Each node is a single digit, so the number along a path is the concatenation of those digits read top to bottom.
  • Depth will not exceed 10: The longest path has at most 10 nodes, so a path number has at most 10 digits. A 10-digit value such as 9,999,999,999 overflows a 32-bit int, but the problem guarantees the total sum fits in a 32-bit int. Since every path number is non-negative, each one is at most the total sum, so each one also fits in a 32-bit int. A plain int accumulator is therefore safe in every language here, and the depth bound of 10 keeps recursion shallow.

Approach 1: DFS with Path Collection

Intuition

One direct approach collects the digits along the current path, then converts that list into a number whenever we reach a leaf. We run a DFS that appends each node's value on the way down and removes it on the way back up, so the list always holds the path from the root to the node we are currently visiting.

This separates the two subproblems cleanly: the DFS handles path enumeration, and a small loop over the digit list handles number construction. It works, but it repeats work. At every leaf we re-scan the full path from scratch to rebuild a number that is mostly the same as its parent's number.

Algorithm

  1. Start a DFS from the root with an empty path list.
  2. At each node, append the node's value to the current path.
  3. If the node is a leaf (both children are null), iterate through the path digits to compute the number and add it to the running total.
  4. Recursively visit the left child and the right child.
  5. After visiting both children, remove the last element from the path (backtrack) so the path is clean for sibling exploration.
  6. Return the total sum.

Example Walkthrough

Input:

123
root

We trace the DFS, tracking path and totalSum:

  1. Visit root 1. Append it, so path = [1]. Node 1 has children, so it is not a leaf.
  2. Recurse left to node 2. Append it, so path = [1, 2]. Node 2 has no children, so it is a leaf. Rebuild the number from the path: 0, then 0*10+1 = 1, then 1*10+2 = 12. Add it, so totalSum = 12. Backtrack: remove 2, so path = [1].
  3. Recurse right to node 3. Append it, so path = [1, 3]. Node 3 is a leaf. Rebuild: 0*10+1 = 1, then 1*10+3 = 13. Add it, so totalSum = 12 + 13 = 25. Backtrack: remove 3, so path = [1].
  4. Both children of node 1 are done. Backtrack: remove 1, so path = []. The DFS finishes.
25
totalSum

Code

The repeated path-to-number conversion is the only inefficiency. When we move from a parent to a child, the number changes by one digit. The next approach removes the redundant work by passing the running number down as a parameter instead of rebuilding it at each leaf.

Approach 2: Recursive DFS with Running Number

Intuition

Instead of collecting paths and converting them at the leaves, we build the number as we descend. If the number formed by the path from the root down to a node's parent is currentNum, then the number at this node is currentNum * 10 + node.val. We carry that running value down through the recursion as a parameter.

This mirrors how a number is read left to right. Start with 0. Read a 4, and the number is 0*10+4 = 4. Read a 9, and it becomes 4*10+9 = 49. Read a 5, giving 49*10+5 = 495. When the recursion reaches a leaf, the parameter already holds the complete path number, so the leaf can return it directly. Each internal node returns the sum of what its two subtrees returned, so the total accumulates through the return values without any shared accumulator.

Algorithm

  1. Define a recursive function dfs(node, currentNum) that takes a node and the number formed so far.
  2. If the node is null, return 0 (no contribution to the sum).
  3. Update the running number: currentNum = currentNum * 10 + node.val.
  4. If the node is a leaf (no children), return currentNum. This path's number is complete.
  5. Otherwise, return dfs(left, currentNum) + dfs(right, currentNum) to sum contributions from both subtrees.

Visualization and Code

Loading animation...

Approach 2 is optimal in time and uses only the recursion stack. The next approach replaces that recursion with an explicit stack, reaching the same O(n) time without relying on recursive calls. This is the form to use when deep recursion is a concern or when recursion is unavailable.

Approach 3: Iterative DFS with Stack

Intuition

We can convert the recursive approach to an iterative one using an explicit stack. The idea is identical: track the running number as we descend, and when we reach a leaf, add the completed number to the total. Instead of the system call stack holding our traversal state, we push (node, currentNum) pairs onto our own stack.

Algorithm

  1. Initialize a stack with the pair (root, root.val).
  2. Initialize totalSum = 0.
  3. While the stack is not empty:
    • Pop a (node, currentNum) pair.
    • If the node is a leaf, add currentNum to totalSum.
    • If the node has a right child, push (right, currentNum * 10 + right.val).
    • If the node has a left child, push (left, currentNum * 10 + left.val).
  4. Return totalSum.

Example Walkthrough

We trace the tree [1, 2, 3]. Each stack entry pairs a node with the running number for the path ending at that node. Since the stack is LIFO, pushing the right child before the left child makes the left child come off the stack first, so the traversal visits the left subtree before the right. The push order only affects visit order, not the final sum, because every leaf's number is added regardless of when it is popped.

1Push root (1, num=1) onto stack
1num=123
1/5

Code