Maximum Depth of Binary Tree
Return the maximum depth of a binary tree — the number of nodes on the longest path from the root down to a leaf.
Open on LeetCode ↗Intuition
Ask each child how deep its subtree is, take the bigger answer, and add one for yourself. An empty tree is depth 0 — that base case plus one line of recursion is the whole solution.
The purest bottom-up recursion: a node's depth is one more than the deeper of its two subtrees, and an empty tree is 0. This 1 + max(left, right) shape recurs across tree problems — diameter, balance checking, and height-based DP all compute it as a side effect.
Approach
Define depth recursively
The depth of an empty tree is 0. The depth of any node is 1 + max(depth(left), depth(right)) — one for the node itself plus the deeper of its two subtrees. This is postorder in disguise: both children must answer before the parent can.
Answers bubble up from the leaves
Leaves compute 1 + max(0, 0) = 1; their parents combine those answers, and so on up to the root. No global state, no counters — each call returns a number and the recursion assembles them.
BFS alternative
Level-order traversal counts levels instead: pop a full level, increment depth, push the next. Same O(n), sometimes preferred when the tree is very deep (avoids recursion-stack limits) or when you need early exit for minimum depth.
Solution & live demo
Common pitfalls
Returning 1 for a null node
if not root:
return 1if not root:
return 0The empty tree has no levels. Returning 1 inflates every path by one and reports a depth one too large for every input, including single-node trees.
Adding instead of taking the max
return 1 + left + right
return 1 + max(left, right)
That counts total nodes on both sides rather than the longest single root-to-leaf path. Depth is about one path, not the whole subtree.
Tracking depth with a mutable global and forgetting to restore it
self.d += 1 dfs(node.left) dfs(node.right)
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
A shared counter incremented on the way down must be decremented on the way back up, or sibling subtrees inherit each other's depth. Returning the value makes the bookkeeping impossible to get wrong.
Edge cases
not root → return 0 immediately.
One side is always empty (depth 0); the recursion effectively walks the chain, and depth equals node count.
Both subtrees report equal depth; max just picks either and adds one.