What 40 Binary Tree Problems Didn't Teach Me Before My FAANG Interview

What 40 Binary Tree Problems Didn't Teach Me Before My FAANG Interview

posted Originally published at www.codeintuition.io 7 min read

The tree round on my first onsite was Root to Leaf Paths. Enumerate every root-to-leaf path in a binary tree. Looked easy. The recursion took about four minutes to write. Running it on the sample input came back with a list where every path ended at the leaf of the last branch the function had visited. The earlier paths had been contaminated. The interviewer watched the screen for two full minutes before the cause clicked: the shared list parameter never got cleaned up between recursive calls. That technique had shown up in practice twice before, but the conditions for when it was required had never internalised. What was missing was the framing that root-to-leaf problems are a class with their own boundary handling, separate from the other recursive tree patterns.

What changed afterwards:

  • Tree problems aren't a single skill. They are six distinct mechanisms (preorder, postorder, root to leaf, level order, LCA, simultaneous traversal), each with its own boundary cases.
  • Fifteen problems chosen by pattern coverage beat forty random problems sorted by acceptance rate.
  • The single biggest mistake on root-to-leaf problems is forgetting to backtrack the shared accumulator after each recursive call.
  • Practice in pattern order, not difficulty order. Each pattern's mechanism transfers to its variants but not to other patterns.

Where the tree prep was breaking

The grinding approach is what most onlines recommend. Open LeetCode's tree tag. Sort by acceptance rate or popularity. Work through the top forty. After about a week the easy ones feel reflexive, after two weeks the mediums start landing more often than not, and by week three the assumption is that tree rounds will be fine.

That assumption broke on the Root to Leaf Paths bug. The problem wasn't hard. It was a class of problem that had been practiced before. What was missing was the recognition that root-to-leaf is its own pattern with its own boundary behaviour, distinct from the postorder problems on the list and distinct from the preorder problems that felt most confident. Forty problems sat behind that interview, and there was no grouping that would have made the root-to-leaf class visible as a class.

The deeper diagnosis was this. What was missing wasn't more problems. It was the grouping that would let problem 1 in a class prepare a candidate for problem 2 in the same class. Forty problems organised by popularity give no transfer. Two problems per pattern, organised by mechanism, give coverage of every interview-grade tree question that's likely to show up.

What started working differently

The rebuild happened pattern by pattern. Each session, pick one of the six patterns. Work through the direct application first (the problem that teaches the mechanism cleanly). Then work through one variant (the problem that proves the mechanism transferred). Two problems per pattern, no more. If the mechanism hadn't clicked after problem two, the answer wasn't to add a third problem in the same pattern. The answer was to go back to problem one and trace it on paper until the mechanism became obvious from the structure of the recursion.

The change in approach looked like this:

Before (grinding random problems) After (two per pattern, in pattern order)
Sort LeetCode tree tag by frequency, do top 40 Pick six patterns, do two problems each, in pattern dependency order
Treat each problem as a separate puzzle to solve Treat each problem as an instance of one of six known mechanisms
Practice difficulty order (easy, then medium, then hard) Practice pattern order, with the direct application before each variant
Recognise solutions you've already seen Recognise which pattern a new problem needs, then derive the solution
Freeze on root-to-leaf backtracking under pressure Walk into root-to-leaf knowing the path parameter is shared and needs cleanup

The key was that the six patterns gave the practice a vocabulary. Preorder. Postorder. Root to leaf. Level order. Lowest common ancestor. Simultaneous traversal. Every binary tree problem that came up, the first question became "which of the six is this?" That single question reorganised everything. Problems that previously felt random started feeling like instances of techniques already met.

What that looked like on the next problem

Three weeks into the rebuild, a friend ran a mock interview and the prompt was Root to Leaf Paths. The exact problem that had broken the onsite.

The framing was different this time. Root to leaf problems share a single accumulator (the path list) across all recursive branches. That sharing is what makes them fast (no per-call allocation), and it is what creates the bug if the accumulator doesn't get cleaned up after each child returns. Recognise the pattern first, write the recursion with the cleanup built in.

def root_to_leaf_paths(root):
    paths = []

    def walk(node, current):
        if node is None:
            return
        current.append(node.value)
        if node.left is None and node.right is None:
            paths.append(list(current))
        else:
            walk(node.left, current)
            walk(node.right, current)
        current.pop()

    walk(root, [])
    return paths

Two things to notice in the code. First, current is a single list that gets passed down through every recursive call. There's no copy at each call, which is what makes the algorithm O(n) plus the cost of producing the output. Second, the current.pop() at the end of walk is the cleanup. After the recursion returns from a child, the appended value gets removed so the sibling subtree sees the path as it was when the parent called it. Without that line, the bug from the original onsite shows up.

The mechanism transfers to the variant. Equal paths asks whether any root-to-leaf path sums to a target. Same skeleton (descend, accumulate, check at leaf, backtrack), different terminal check. Once root to leaf paths is solid, equal paths is a five-minute extension. The root to leaf paths lesson walks the backtracking explicitly, which is the part that gets glossed over in most textbook reading.

Why this works (pattern based practice)

The reason pattern grouping holds up under interview pressure has a name in learning science: near transfer versus far transfer. Practicing forty random problems builds a lot of near transfer skill (the ability to handle problems that look like the ones already practiced) and almost no far transfer (the ability to reliably handle a new problem with a slightly different surface).

Practicing two problems per pattern, in pattern order, inverts that ratio. The first problem teaches the mechanism. The second forces a variation that confirms the mechanism transferred, not the surface form. Past two problems per pattern, the marginal value drops fast, because the third is rehearsing the same mechanism with diminishing returns.

The six patterns also explain why difficulty order is the wrong sequencing. A medium postorder problem can be easier than a hard preorder problem, if postorder is already understood and preorder hadn't been met yet. Difficulty is a function of "has this mechanism been seen before?" not a function of the problem's intrinsic complexity. Pattern order respects that dependency. Postorder builds on preorder's recursive structure. Root to leaf reuses postorder's return mechanism plus the backtracking subtlety. Level order is a paradigm shift to a queue-based approach. LCA introduces multi node reasoning. Simultaneous traversal scales LCA's reasoning to two trees.

What I'd tell someone starting tree prep

If you're three weeks into tree practice and tree rounds still feel random, the shift to make is to stop grinding and start grouping.

A protocol that worked for the rebuild:

  1. Before each session, name the pattern you'll practice (preorder, postorder, root to leaf, level order, LCA, or simultaneous traversal). Pick one. Don't mix patterns within a session.
  2. Solve the direct application first (the problem that teaches the mechanism cleanly). For postorder, that's height of binary tree. For root to leaf, that's root to leaf paths. For LCA, that's the canonical lowest common ancestor problem.
  3. Trace the solution on paper after writing it. If you can't narrate why each step preserves the mechanism, the mechanism hasn't clicked. Go back to the recursion and walk it variable by variable.
  4. Solve the variant second. Diameter after height. Equal paths after root to leaf paths. Distance between nodes after LCA. If the variant feels like a fresh problem instead of an extension, the first problem hadn't internalised.
  5. Move to the next pattern only after the current pattern's variant feels like a five-minute job. The transfer signal is "the pattern got recognised first, then the solution wrote itself," not "it took careful work to get there."

The protocol slowed things down at first. Two problems per session felt like less practice than four problems per session. The payoff was that the slower practice transferred. When the next mock interview surfaced a tree problem that hadn't been seen, the pattern recognition kicked in first and the recursion followed. That sequence was what was missing from the original forty-problem grind.

The grouping is what got built into Codeintuition's tree course, because watching engineers grind through forty problems with no transfer was the failure mode that kept showing up across every prep cohort. Pattern-first practice changed how trees felt to walk into, and the course now teaches the same restructure that made the difference.

Originally posted on my own blog, with the full fifteen-problem list grouped by pattern and a recursion-bug catalogue.

What's a tree problem that finally made a pattern click for you, where the textbook explanation hadn't?

More Posts

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

Your Tech Stack Isn’t Your Ceiling. Your Story Is

Karol Modelskiverified - Apr 9

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

Big O Notation: What I Wish I'd Known Before My First Interview

prakhar_srv - May 23

The Senior Angular Take‑Home That Made Me Rethink Tech Interviews

Karol Modelskiverified - Apr 2
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

2 comments
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!