Average of Levels in Binary Tree
Use a queue, as in level-order traversal. At the start of each round the queue holds exactly one whole level. Remember how many nodes it holds, pop exactly that many while adding their values, and push their children behind them. Then divide the round's sum by that count.
A round is correct when it pops exactly the size nodes that were in the queue at its start, and nothing else. The children it pushes wait behind them for the next round.
Problem
You are given the root of a binary tree.
For each level of the tree, find the average of the node values on that level. Return one average per level, from the top level (the root) down to the bottom level.
A level is all the nodes that are the same distance from the root. Answers within 10^-5 of the exact average are accepted.
The root of a binary tree. The tree is never empty.
An array of decimal numbers: the average of each level, top to bottom.
Level 0 is just 3, so its average is 3. Level 1 has 9 and 20: (9 + 20) / 2 = 14.5. Level 2 has 15 and 7: (15 + 7) / 2 = 11.
This tree has 15 and 7 as the children of 9 instead of 20. The level averages are still 3, 14.5 and 11.
- • The number of nodes is between 1 and 10^4.
- • −2^31 ≤ Node.val ≤ 2^31 − 1
- • Answers within 10^-5 of the exact average are accepted.
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
Is one round of the algorithm one node, or all the nodes that share a depth?
- 2.
Which traversal hands me the nodes of one level together: depth-first or breadth-first?
- 3.
Should I divide by the number of nodes on this level, or by the number of nodes in the whole tree?
- 4.
Node values can be as large as 2^31 − 1. What happens if two of them are added in a 32-bit int?
- 5.
If I do not know how deep the tree is, how will I know when to stop?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Walk the whole tree once for each depth, adding up the nodes at that depth | O(N · H) | O(H) |
| Optimal | Pop one whole level per round from a queue; the round's size tells you how many nodes to pop | O(N) | O(W) |
Why does this belong to this pattern?
- “average of the values on each level”One number per level, so the answer is grouped by depth, not by path or by subtree.
- “each level”A level is the set of nodes that share a depth. That is exactly one BFS round.
- “from top to bottom”Rounds run from the top down, so the order of the rounds is the order of the answer. No sorting is needed.
This is the anchor for the sub-pattern: one BFS round is exactly one level, so any per-level number is the round's total divided by the round's size. The new part compared with plain level order is the divisor: it is this round's size, not the size of the whole tree. Also, the sum needs 64 bits, because each node value can be as large as 2^31 − 1.
Don't make this mistake
Two nodes of value 2^31 − 1 already overflow a 32-bit int. On [2147483647, 2147483647, 2147483647] the second level's int sum wraps around to −2, so its average comes out as −1 instead of 2147483647.
On [3, 9, 20, null, null, 15, 7] the second level has sum 29 and size 2. Integer division gives 14, but the answer is 14.5.
Each answer is about one level. On [3, 9, 20, null, null, 15, 7] there are 5 nodes in total, so the second level would become 29 / 5 = 5.8 instead of 14.5. The divisor is the number of nodes in this round.
The second level would also add the root's 3, so the answer becomes (3 + 9 + 20) / 2 = 16 instead of 14.5. Each round must start from zero.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Tree BFS translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.