You are given the root of a binary tree containing digits from 0 to 9 only.
Each root-to-leaf path in the tree represents a number.
1 -> 2 -> 3 represents the number 123.Return the total sum of all root-to-leaf numbers. Test cases are generated so that the answer will fit in a 32-bit integer.
A leaf node is a node with no children.
Example 1:
Input: root = [1,5,1,null,null,null,6]
Output: 131Explanation:
The root to leaf path 1 -> 5 represents the number 15.
The root to leaf path 1 -> 1 -> 6 represents the number 116.
The sum of both the numbers is: 15 + 116 = 131.
Example 2:
Input: root = [1,2,1,9,2,3,4]
Output: 478Explanation:
The root to leaf path 1 -> 2 -> 9 represents the number 129.
The root to leaf path 1 -> 2 -> 2 represents the number 122.
The root to leaf path 1 -> 1 -> 3 represents the number 113.
The root to leaf path 1 -> 1 -> 4 represents the number 114.
The sum the numbers is: 129 + 122 + 113 + 114 = 478.
Constraints:
1 <= number of nodes in the tree <= 10000 <= Node.val <= 910.Before attempting this problem, you should be comfortable with:
Each root-to-leaf path in the tree represents a number, where digits are concatenated from root to leaf. As we traverse down the tree, we build the number by multiplying the accumulated value by 10 and adding the current node's value. When we reach a leaf node, we have a complete number to add to our sum. DFS naturally follows paths from root to leaf, making it ideal for this problem.
dfs function that takes the current node and the accumulated number so far.0 (base case for empty subtrees).num = num * 10 + cur.val.dfs from the root with an initial number of 0.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
def dfs(cur, num):
if not cur:
return 0
num = num * 10 + cur.val
if not cur.left and not cur.right:
return num
return dfs(cur.left, num) + dfs(cur.right, num)
return dfs(root, 0)Where is the number of nodes and is the height of the given tree.
Instead of going deep first, we can process the tree level by level using a queue. Each entry in the queue stores both a node and the number accumulated along the path to reach that node. When we dequeue a leaf node, we add its accumulated number to the total. BFS ensures we visit all nodes while tracking each path's value independently.
0 and a queue with the root node and initial number 0.num = num * 10 + cur.val.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
res = 0
q = deque([(root, 0)])
while q:
cur, num = q.popleft()
num = num * 10 + cur.val
if not cur.left and not cur.right:
res += num
continue
if cur.left:
q.append((cur.left, num))
if cur.right:
q.append((cur.right, num))
return resWe can simulate the recursive DFS using an explicit stack instead of the call stack. This avoids potential stack overflow for very deep trees. The key insight is to always go left while tracking right children on the stack for later processing. Each stack entry remembers the accumulated number at that point so we can correctly continue building path values.
0, an empty stack, and start with the root node and number 0.num = num * 10 + cur.val.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumNumbers(self, root: Optional[TreeNode]) -> int:
res = 0
stack = []
cur, num = root, 0
while cur or stack:
if cur:
num = num * 10 + cur.val
if not cur.left and not cur.right:
res += num
stack.append((cur.right, num))
cur = cur.left
else:
cur, num = stack.pop()
return resWhere is the number of nodes and is the height of the given tree.
Morris traversal allows us to traverse the tree without using extra space for a stack or recursion. It temporarily modifies the tree by creating links from predecessors back to their successors. The challenge here is tracking the accumulated number: when we return to a node via a temporary link, we need to "undo" the digits we added while going down the left subtree. We track the number of steps taken to reach the predecessor and divide by the corresponding power of 10 to remove those digits.
10 for quick division.null, create a temporary link to current, add digit to number, and move left.10^steps to remove the left subtree digits. Move right.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumNumbers(self, root: Optional[TreeNode]) -> int:
res = 0
cur = root
num = 0
power = [1] * 10
for i in range(1, 10):
power[i] *= power[i - 1] * 10
while cur:
if not cur.left:
num = num * 10 + cur.val
if not cur.right:
res += num
cur = cur.right
else:
prev = cur.left
steps = 1
while prev.right and prev.right != cur:
prev = prev.right
steps += 1
if not prev.right:
prev.right = cur
num = num * 10 + cur.val
cur = cur.left
else:
prev.right = None
if not prev.left:
res += num
num //= power[steps]
cur = cur.right
return resA frequent mistake is adding the accumulated number to the result at every node instead of only at leaf nodes. The problem specifically asks for root-to-leaf path numbers, so you must check that both left and right children are null before adding to the sum. Adding at internal nodes will count partial paths and produce incorrect results.
When building the number along a path, you must multiply the current accumulated value by 10 before adding the new digit: num = num * 10 + node.val. A common error is adding the digit first or forgetting to multiply, which produces single-digit values or incorrect concatenation. Remember that each level represents a new decimal place.
When the tree has only a root node with no children, that single node is itself a leaf. Some implementations incorrectly return 0 for this case or fail to recognize it as a valid path. Ensure your base case properly handles when the root exists but has no children, returning just the root's value as the complete number.