p12 Max Depth — Progressive Hints

Rule: ONE hint at a time, 5-min timer between.


Hint 1 — Pattern

What does “depth of a tree” mean in terms of the depths of its left and right subtrees? Write the relation in plain English.


Hint 2 — Base case

What’s the depth of an empty tree? (Hint: 0.) What’s the depth of a single-node tree? (1 — the root counts.)


Hint 3 — The recurrence

depth(node) = 1 + max(depth(left), depth(right))

The +1 counts the current node; we add it to the deeper of the two subtrees.


Hint 4 — Pseudocode

Recursive:

def depth(node):
    if node is None: return 0
    return 1 + max(depth(node.left), depth(node.right))

BFS (level-by-level):

queue = deque([root]); depth = 0
while queue:
    depth += 1
    for _ in range(len(queue)):     # snapshot level size
        cur = queue.popleft()
        if cur.left:  queue.append(cur.left)
        if cur.right: queue.append(cur.right)
return depth

Hint 5 — Full + traps

Time O(N), space O(H) (recursive) or O(W) (BFS).

Trap 1 — placing +1 wrong: max(1 + ..., 1 + ...) works (each side adds its own root); 1 + max(...) is cleaner. Both correct; the latter is idiomatic.

Trap 2 — BFS without len(queue) snapshot: if you increment depth on every pop, you count NODES not LEVELS. The snapshot pins the level boundary.

Trap 3 — DFS with stack: must carry the depth as (node, depth) pair; len(stack) is unrelated to path length.

Trap 4 — Don’t transplant to LC 111 (min depth): the symmetry breaks for nodes with one missing child. A node with left=None, right=non-empty is NOT a leaf — its depth-to-nearest-leaf goes through the right subtree, not 0.

Why this matters beyond this problem: the recurrence f(node) = combine(node.val, f(left), f(right)) is the template for EVERY “compute an integer/property of a tree” problem. Internalize the template.