2Brute2Best
πŸ”₯0

Maximum Depth of Binary Tree

EasyΒ·LeetCode #104Basic Anchor
LeetCode
30-Second Mental ModelTree DFS, traversal: each child returns its depth, and the parent combines the two answers
Complexity:O(N)β†’O(N)
Key Insight

Ask both children how deep their subtrees are. The deeper side plus this node is the depth at this node. An empty child returns 0, so a leaf returns 1 + max(0, 0) = 1. The base case is the empty tree, which is 0 levels.

Core Validity Invariant

The depth of a subtree is 1 + the larger child depth, and an empty subtree has depth 0. That one rule covers every node, leaves included.

01

Problem

You are given the root of a binary tree. Return its depth: the number of nodes on the longest path from the root down to a leaf.

An empty tree has depth 0.

Input

The root of a binary tree. The tree may be empty.

Output

A single number: the depth of the tree.

Example 1
Input: root = [3, 9, 20, null, null, 15, 7]
Output: 3

The longest path is 3 β†’ 20 β†’ 15 (or 3 β†’ 20 β†’ 7). That path has 3 nodes.

Example 2
Input: root = [1, null, 2]
Output: 2

The only path is 1 β†’ 2, which has 2 nodes.

Example 3
Input: root = []
Output: 0

There are no nodes, so there are no levels.

Constraints
  • β€’ The number of nodes in the tree is in the range [0, 10^4].
  • β€’ βˆ’100 ≀ Node.val ≀ 100
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck β€” each hint is counted.

  1. 1.

    How many nodes are on a path that is just one node? What depth should that give?

  2. 2.

    If I know the depth of the left subtree and the depth of the right subtree, can I get the depth of the whole tree?

  3. 3.

    Only the longer side decides the longest path. Do I need both sides' numbers, or just the bigger one?

  4. 4.

    What should an empty child contribute to the depth: 0 or 1? Why?

  5. 5.

    Does this question count every node, or only the nodes on one longest path?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceWalk the tree one level at a time with a queue; the number of levels is the depthO(N)O(W)
OptimalEach node returns 1 + the larger of its children's answers; an empty child returns 0O(N)O(H)
09

Why does this belong to this pattern?

Clues in the problem statement
  • β€œdepth of the tree”The longest root-to-leaf path. It is the larger side, not the sum of the two sides.
  • β€œroot with two subtrees”A tree is one root and two smaller trees, so the answer for the whole tree can be built from the answers for the parts.
  • β€œempty tree”The base case: no nodes means 0 levels.
depth(node) = 1 + max(depth(left), depth(right))+depth(null) = 0+answer = depth(root)β†’Tree DFS, traversal: each child returns its depth, and the parent combines the two answers

This is the first and simplest tree question: the answer for a node comes from the answers of its children. The recursion visits the children first and combines the results on the way back up. Same Tree and Symmetric Tree keep the same walk but compare two trees instead of combining one, and that is where the traversal sub-pattern changes.

10

Don't make this mistake

Returning 1 for an empty node
βœ— if (!root) return 1;
βœ“ if (!root) return 0;

The two empty children of a leaf would each count as one level, so a single node looks like it has a level below it. On [1] the wrong version returns 2. An empty tree returns 1 as well instead of 0. Empty means zero levels.

Adding the two sides instead of taking the larger one (pattern confusion: that counts nodes)
βœ— return 1 + maxDepth(root->left) + maxDepth(root->right);
βœ“ return 1 + max(maxDepth(root->left), maxDepth(root->right));

This counts every node, so it returns the size of the tree, not its depth. On [3, 9, 20, null, null, 15, 7] the wrong version returns 5 (the number of nodes), while the depth is 3. A depth is a longest path, so only the deeper side counts.

Counting nodes instead of levels in BFS
βœ— while (!q.empty()) { TreeNode* node = q.front(); q.pop(); levels++; ... }
βœ“ size_t levelSize = q.size(); for (size_t i = 0; i < levelSize; i++) { ... }

Adding one per popped node counts nodes. On [3, 9, 20, null, null, 15, 7] that gives 5. A round has to pop exactly one level, so the size of the queue is read once before the loop, and only then is the count increased.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Tree DFS translate into production architectures and low-level memory mechanics.