◀ THE GRIND — TREES

Construct Binary Tree From Preorder And Inorder Traversal

MEDIUM✓ CHIP-TIMEDLC #105 — FULL STATEMENT ↗

The drill: Two traversal orders, one unique tree — rebuild the exact original shape from a preorder list and an inorder list of the same distinct values.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

Two lists arrive describing the same binary tree from different angles — one in preorder, one in inorder — and the job is rebuilding the one tree that produces both.

Every value in the tree is distinct, which is what makes the reconstruction unambiguous: there's exactly one tree shape consistent with both traversals at once.

The output is the root of that rebuilt tree, matching the original in every branch, every leaf, and every null gap.

EX 01
preorder = [3, 9, 20, 15, 7] · inorder = [9, 3, 15, 20, 7]
[3, 9, 20, null, null, 15, 7]
CLASSIC UNBALANCED SHAPE
EX 02
preorder = [1] · inorder = [1]
[1]
SINGLE NODE
EX 03
preorder = [] · inorder = []
[]
EMPTY
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Preorder always names the current subtree's root first. Inorder splits everything left of that root's position into the left subtree and everything right of it into the right subtree.

HINT 2 THE STRUCTURE

Once you know the root and where it sits in inorder, the sizes of the left and right pieces fall out immediately — same trick applies recursively to every subtree.

HINT 3 ONE STEP FROM THE ANSWER

Recurse with an index into preorder (advancing by one each call) and a (left, right) window into inorder. A hashmap from value to inorder index turns "where does the root sit" into an O(1) lookup instead of a scan.

COACH'S BOARD — THE PATTERN, STEP BY STEP
TWO LISTS, ONE TREEPATTERN · HASHMAP + INDEX WINDOWpreorder = [3, 9, 20, 15, 7] · inorder = [9, 3, 15, 20, 7]
STEP 1

Preorder always names a subtree's root first: 3, 9, 20, 15, 7. Inorder tells us where each root splits left from right.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/construct-binary-tree-from-preorder-and-inorder-traversal.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        index = {v: i for i, v in enumerate(inorder)}
        pos = [0]

        def helper(lo: int, hi: int) -> Optional[TreeNode]:
            if lo > hi:
                return None
            root_val = preorder[pos[0]]
            pos[0] += 1
            root = TreeNode(root_val)
            mid = index[root_val]
            root.left = helper(lo, mid - 1)
            root.right = helper(mid + 1, hi)
            return root

        return helper(0, len(inorder) - 1)
TIME O(N)SPACE O(N)PYTHON · RACE PACE · 17 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED