root
of a binary tree, return the average value of the nodes on each level in the form of an array. Answers within 10-5
of the actual answer will be accepted.
Example 1:
Input: root = [3,9,20,null,null,15,7] Output: [3.00000,14.50000,11.00000] Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].
Example 2:
Input: root = [3,9,20,15,7] Output: [3.00000,14.50000,11.00000]
Constraints:
[1, 104]
.-231 <= Node.val <= 231 - 1
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding the average value at each level of a binary tree involves visiting every single level in the tree. We calculate the sum of all values present at each level. After the sum is calculated, we divide it by the count of nodes at that level to find the average.
Here's how the algorithm would work step-by-step:
def average_of_levels(root):
if not root:
return []
level_averages = []
nodes_queue = [root]
while nodes_queue:
level_length = len(nodes_queue)
level_sum = 0
# Iterate over all nodes in current level
for _ in range(level_length):
node = nodes_queue.pop(0)
level_sum += node.val
# Add children to queue for next level
if node.left:
nodes_queue.append(node.left)
if node.right:
nodes_queue.append(node.right)
# Calculate average and record it for level
average = float(level_sum) / level_length
level_averages.append(average)
return level_averages
To find the average value at each level of a binary tree efficiently, we'll visit each level one by one. We'll keep a running sum of the node values and count how many nodes are at that level so we can find the average.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def averageOfLevels(root):
levels_averages = []
nodes_to_do = [root]
# Process each level of the tree
while nodes_to_do:
level_sum = 0
level_size = 0
next_level_nodes = []
# Iterate through the nodes at the current level
for node in nodes_to_do:
level_sum += node.val
level_size += 1
# Add children to the queue for the next level
if node.left:
next_level_nodes.append(node.left)
if node.right:
next_level_nodes.append(node.right)
# Store average value for the current level
average = float(level_sum) / level_size
levels_averages.append(average)
# Update the queue for the next level traversal.
nodes_to_do = next_level_nodes
return levels_averages
Case | How to Handle |
---|---|
Null or empty tree (root is null) | Return an empty list immediately since there are no levels to average. |
Tree with only one node (root only) | Return a list containing only the root's value as the average of level 0. |
Tree with all nodes having the same value. | The average at each level will be the same as the node value, handled correctly by level order traversal. |
Tree with very large or very small node values, leading to potential integer overflow during sum calculation at a level. | Use long or double to store the sum of node values at each level to prevent overflow. |
Highly skewed tree (e.g., all nodes on one branch) | The level order traversal still works correctly, averaging only the node at each level. |
Tree with a very large number of levels, potentially exceeding stack space if using recursion. | Use iterative level order traversal (BFS) to avoid stack overflow errors. |
Floating-point precision issues when calculating the average. | Use double to store the average and be aware of potential minor inaccuracies. |
Negative node values. | The average calculation will handle negative values correctly as part of the sum. |