LeetCode #637 Easy

Average of Levels in Binary Tree

Average of Levels in Binary Tree: return the average value of the nodes on each level, from the root downward, as a list of doubles.

Constraints
  • The number of nodes in the tree is in the range [1, 10⁴]
  • -2³¹ <= Node.val <= 2³¹ - 1
  • Answers within 10⁻⁵ of the actual answer are accepted
treebreadth-first searchbinary tree
Open on LeetCode ↗
Average of Levels in Binary Tree diagramA labelled diagram of the structure this problem turns on.each level collapses to one number: sum ÷ count39201573 ÷ 1 = 3.0(9+20) ÷ 2 = 14.5(15+7) ÷ 2 = 11.0the queue's length at the start of a level IS the divisor
02

Intuition

Each level needs two numbers — a running sum and a count — and the count is already known before the level starts, because it is the queue's length at that moment. So a breadth-first walk that snapshots the queue size gets the divisor for free, sums the level as it drains, and emits one average per level without storing any of the values.

How to spot this pattern

Reducing each level to one number is the level-order loop with a different accumulator — sum here, max for Largest Value in Each Row, last element for Right Side View. Recognising the shared skeleton means only the reduction has to be rewritten.

03

Approach

Try it first

Before reading on: identify where the divisor for each level comes from without collecting the level into a list. Then work out which type the running sum needs in a fixed-width language, given the stated value range.

1

The queue length is the divisor

At the top of each iteration the queue holds exactly the nodes of one level, so count = len(queue) is simultaneously the number of nodes to pop and the denominator of the average. That coincidence is what makes the problem clean: there is no need to collect the level into a list and take its length afterwards. Popping exactly count nodes drains the current level while the children pushed during that loop wait behind them for the next round.

2

Accumulate a sum, not a list

Only the total and the count are needed, so the values themselves can be discarded as they are read. Keeping a running total instead of a per-level list drops the auxiliary space for the level from O(w) to O(1), though the queue itself still holds up to O(w) nodes so the overall bound is unchanged. The gain is clarity more than memory: the code states directly that a level is being reduced to a single number rather than materialised and then reduced.

3

Precision and why integer division fails

Node values reach ±2³¹ - 1 and a level can hold many of them, so the sum must be held in a 64-bit type in C++ and Java or it overflows before the division ever happens. The division itself must be floating point: total / count in Python 3 already produces a float, but in Java total / count on two ints truncates, so one operand must be cast to double. Answers within 10⁻⁵ are accepted, which a double comfortably satisfies. Time is O(n), space O(w).

04

Solution & live demo

1from collections import deque
2 
3 
4class Solution:
5 def averageOfLevels(self, root):
6 averages = []
7 queue = deque([root])
8 while queue:
9 count = len(queue)
10 total = 0
11 for _ in range(count):
12 node = queue.popleft()
13 total += node.val
14 if node.left:
15 queue.append(node.left)
16 if node.right:
17 queue.append(node.right)
18 averages.append(total / count)
19 return averages
05

Common pitfalls

Overflowing the level sum

✗ Wrong
int total = 0;
for (...) total += node->val;
✓ Right
long total = 0;
for (...) total += node->val;

Values reach 2³¹ - 1, so two large nodes on one level already exceed the signed 32-bit range. The sum wraps negative and the average comes out wildly wrong before any division occurs.

Integer division truncating the average

✗ Wrong
averages.add(total / count);
✓ Right
averages.add((double) total / count);

In Java and C++ dividing two integers discards the fractional part, so a level of 9 and 20 averages to 14 instead of 14.5. One operand must be floating point.

Re-reading the queue length inside the level loop

✗ Wrong
for (int i = 0; i < queue.size(); i++)
✓ Right
int count = queue.size();
for (int i = 0; i < count; i++)

The queue grows as children are enqueued, so the loop bound keeps moving and the level absorbs nodes from the level below, corrupting both the sum and the divisor.

06

Edge cases

Single node tree

One level, and the average equals the root's value.

Level with one node

The sum divided by one returns that value unchanged.

Negative values

Sums and averages may be negative; nothing about the method assumes positivity.

Large values near the int limit

The running sum must be 64-bit or it overflows mid-level.

Skewed tree

Every level holds one node, so the output mirrors the chain of values.

07

Complexity

Time
O(n)
Space
O(w)
One enqueue and one dequeue per node. Only a sum and a count are held per level, never the values.