Minimum Depth of Binary Tree asks for the shortest distance from the root to the nearest leaf. It is a clean lesson in choosing the right traversal: a breadth-first sweep finds the answer the instant it pops the first leaf, often without touching most of the tree.
Problem. Given the root of a binary tree, return its minimum depth — the number of nodes
along the shortest path from the root down to the nearest leaf (a node with no children). If the
tree is empty, the depth is 0.
Example: the tree [3, 9, 20, null, null, 15, 7] → answer 2. The shortest root-to-leaf path is
3 → 9, and 9 is a leaf, so it has just two nodes on it.
The slow way first
The natural first instinct is depth-first recursion: the minimum depth of a node is 1 + min(left depth, right depth). That works, but it has a subtle trap and it always explores the entire tree. To find the shortest path you must walk every branch all the way down before you can compare them — even branches that are far deeper than the nearest leaf.
The question to ask: which leaf is closest to the root? If we could visit nodes strictly in order of how deep they are, the first leaf we meet would automatically be the closest one — and we could stop right there.
The idea: breadth-first, level by level
A breadth-first (level-order) traversal uses a queue and drains the tree one depth at a time: first the root, then everything at depth 2, then everything at depth 3, and so on. Tag each node with its depth as you enqueue it. The first leaf you dequeue is guaranteed to be at the shallowest depth, so its depth is the answer — and you stop immediately.
The key insight: because BFS never visits a deeper node before a shallower one, the first leaf it reaches cannot be beaten. That lets us return early instead of exploring the whole tree.
Walk through it
Step through the animation. The root 3 goes into the queue at depth 1. We pop it, see it has children, and enqueue 9 and 20 at depth 2. Next we pop 9 — it has no children, so it is a leaf at depth 2. We return 2 and never look at 15 or 7 down on depth 3.
Pseudocode
if the tree is empty:
return 0
put (root, depth = 1) into a queue
while the queue is not empty:
take (node, depth) from the FRONT of the queue
if node has no left child and no right child:
return depth # first leaf popped = nearest leaf
if node has a left child: enqueue (left, depth + 1)
if node has a right child: enqueue (right, depth + 1)The Python solution
from collections import deque
def min_depth(root):
if root is None:
return 0
queue = deque([(root, 1)])
while queue:
node, depth = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append((node.left, depth + 1))
if node.right:
queue.append((node.right, depth + 1))dequeis a double-ended queue;popleft()pulls from the front in O(1), which is what makes this breadth-first.- Each queue entry is a pair
(node, depth)so every node carries its own level with it. - Line 9 is the leaf test — a node with no left and no right child. The very first time it is true, we are at the shallowest leaf.
- Line 10 returns that depth immediately, so we never process the levels below it.
- We only enqueue children that actually exist, each tagged with
depth + 1.
Complexity
| Case | Time | Notes |
|---|---|---|
| Worst case (no early leaf) | O(n) (moderate) | every node visited once |
| Typical (shallow leaf) | ≤ O(n) (moderate) | BFS stops at the first leaf |
O(n) (moderate)In the worst case (a tree where the nearest leaf is at the bottom) we still touch every node, so the time is O(n). The space is O(n) for the queue, which at its widest can hold a whole level of the tree.
When this pattern shows up
When a problem asks for the shortest path, the nearest target, or the minimum number of steps in a tree or graph, reach for BFS with a queue. Because it expands level by level, the first time it reaches a goal it has found the shortest route — let it return early.
Do not confuse this with maximum depth. A common bug is the naive recursion 1 + min(left, right): for
a node with only one child, one side is empty and reports depth 0, which wrongly makes the node look
like a leaf. BFS sidesteps that entirely by checking for an actual leaf (no children at all).
Practice
For the tree 3 → (9, 20) with 20 → (15, 7), which node does BFS pop second, and is it a leaf?
1. Why does BFS find the minimum depth as soon as it pops the first leaf?
2. What does each entry in the queue store?
3. What is the minimum depth of the example tree 3 → (9, 20), 20 → (15, 7)?
4. Why is the naive recursion 1 + min(left, right) buggy for minimum depth?