To find the largest value in each row, we need to visit all nodes level by level. BFS naturally processes nodes in level order using a queue. For each level, we track the maximum value seen among all nodes at that depth.
null, return an empty list.rowMax with the first node's value.rowMax if needed, and enqueue its children.rowMax to the result list.# 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 largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
res = []
q = deque([root])
while q:
row_max = q[0].val
for _ in range(len(q)):
node = q.popleft()
row_max = max(row_max, node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
res.append(row_max)
return resWe can also solve this with DFS by tracking the current depth as we traverse. When we reach a node, if it's the first node at that depth, we add it to the result. Otherwise, we compare it with the existing maximum for that depth and update if necessary.
null, return.level equals the size of the result list, append the node's value (first node at this depth).res[level] to be the maximum of its current value and the node's value.level + 1.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 largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
res = []
def dfs(node, level):
if not node:
return
if level == len(res):
res.append(node.val)
else:
res[level] = max(res[level], node.val)
dfs(node.left, level + 1)
dfs(node.right, level + 1)
dfs(root, 0)
return resThe recursive DFS can be converted to an iterative approach using a stack. Each stack entry stores both the node and its level. This avoids recursion overhead while maintaining the same logic.
null, return an empty list.(root, 0) and an empty result list.(node, level) from the stack.level equals the result list size, append the node's value.res[level] to the maximum of its current value and the node's value.level + 1.# 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 largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
res = []
stack = [(root, 0)]
while stack:
node, level = stack.pop()
if level == len(res):
res.append(node.val)
else:
res[level] = max(res[level], node.val)
if node.right:
stack.append((node.right, level + 1))
if node.left:
stack.append((node.left, level + 1))
return resForgetting to check if the root is null before processing leads to null pointer exceptions or runtime errors. Always add an early return for the empty tree case, returning an empty list rather than attempting to traverse a non-existent tree.
When tracking the maximum value for each row, initializing rowMax to 0 or a small positive number fails for trees with negative values. The correct approach is to initialize rowMax with the first node's value in that row, or use Integer.MIN_VALUE (or equivalent) to ensure negative values are handled correctly.
In BFS, you must process all nodes at the current level before moving to the next. A common mistake is not capturing the queue size before the inner loop, causing nodes from the next level to be processed prematurely. Always store queue.size() at the start of each level iteration and use that fixed count for the inner loop.