Given the root
of a binary tree, return an array of the largest value in each row of the tree (0-indexed).
Example 1:
Input: root = [1,3,2,5,3,null,9] Output: [1,3,9]
Example 2:
Input: root = [1,2,3] Output: [1,3]
Constraints:
[0, 104]
.-231 <= Node.val <= 231 - 1
This problem asks to find the largest value in each row of a binary tree. We can solve this using either Breadth-First Search (BFS) or Depth-First Search (DFS).
This approach uses a queue to process nodes level by level.
Algorithm:
Initialization: Create a queue q
and add the root node to it. Initialize an empty list ans
to store the largest values of each row.
Level Processing: While the queue is not empty:
size
of the queue (number of nodes at the current level).maxVal
to negative infinity.size
times:
maxVal
to the maximum of maxVal
and the node's value.maxVal
to ans
.Return: Return ans
.
Time Complexity: O(N), where N is the number of nodes in the tree. Each node is visited and processed exactly once.
Space Complexity: O(W), where W is the maximum width of the tree. In the worst case (a complete binary tree), W can be proportional to N. The queue stores nodes from at most one level at a time.
This approach uses recursion to traverse the tree.
Algorithm:
Initialization: Create an empty list ans
to store the largest values of each row.
Recursive Function dfs(root, level)
:
root
is null, return.level
is equal to the size of ans
, it means we are encountering a new row, so append root.val
to ans
.ans[level]
with the maximum of the current value and root.val
.dfs
for the left and right children with level + 1
.Call dfs: Call dfs(root, 0)
to start the traversal.
Return: Return ans
.
Time Complexity: O(N), where N is the number of nodes in the tree. Each node is visited and processed exactly once.
Space Complexity: O(H), where H is the height of the tree. This is due to the recursive call stack. In the worst case (a skewed tree), H can be proportional to N.
BFS:
from collections import deque
def largestValues(root):
ans = []
if not root:
return ans
q = deque([root])
while q:
size = len(q)
max_val = float('-inf')
for _ in range(size):
node = q.popleft()
max_val = max(max_val, node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
ans.append(max_val)
return ans
DFS:
def largestValues_dfs(root):
ans = []
def dfs(node, level):
if not node:
return
if level == len(ans):
ans.append(node.val)
else:
ans[level] = max(ans[level], node.val)
dfs(node.left, level + 1)
dfs(node.right, level + 1)
dfs(root, 0)
return ans
Both BFS and DFS provide efficient solutions to this problem, with similar time complexities. The choice between them might depend on factors like personal preference, memory constraints (BFS might be slightly better for very wide trees), or whether you need to traverse the tree in a specific order. The provided code snippets show implementations in Python; adapting them to other languages (Java, C++, Go, TypeScript, Rust) is straightforward, using the equivalent data structures (queues, lists, vectors, etc.).