InterviewPrepKit

Home / Coding / Trees

Construct Binary Tree from Inorder and Postorder Traversal

medium Original β†—
Solving tips
  • Core recipe: the last postorder value is the root; find it in inorder and everything left/right of that index is the left/right subtree.
  • Reach O(n) by precomputing a value->index hash map over inorder and recursing on index ranges instead of slicing arrays (slicing plus linear search is the O(n^2) trap).
  • Elegant variant: read postorder from the back with pop() and build the RIGHT subtree before the left, since reversed postorder is root, right, left.
  • Watch off-by-ones: the left subtree has mid - in_lo nodes, and the right postorder range excludes the root (ends at post_hi - 1). This relies on distinct values; target O(n) time and space.

Problem

You are given two integer arrays describing the same binary tree: inorder (the sequence of node values from an inorder traversal) and postorder (the sequence from a postorder traversal). All node values are distinct. Rebuild the tree and return its root.

Recall the traversal orders: inorder visits left subtree, node, right subtree; postorder visits left subtree, right subtree, node.

Examples

Example 1

Input:  inorder = [9, 3, 15, 20, 7], postorder = [9, 15, 7, 20, 3]
Output: the tree

        3
       / \
      9   20
         /  \
        15   7

The last postorder value (3) is the root; everything left of 3 in inorder ([9]) is the left subtree, everything right ([15, 20, 7]) is the right subtree.

Example 2

Input:  inorder = [-1], postorder = [-1]
Output: a single node with value -1

One value gives a one-node tree.

Example 3

Input:  inorder = [1, 2, 3], postorder = [1, 2, 3]
Output: a right-leaning chain 3 β†’ 2 β†’ 1? No β€” check: root is 3 (last of postorder);
        in inorder everything is LEFT of 3, so 3 has only a left subtree:
        3 ← 2 ← 1 (each node is its parent's left child)

The split position in inorder decides which side each element belongs to.

Constraints

  • 1 <= inorder.length <= 3000, postorder.length == inorder.length
  • -3000 <= values <= 3000, all values distinct (this is what makes the split unambiguous)
  • Both arrays are guaranteed to be valid traversals of the same tree.
  • Expected complexity: O(n) time is achievable; O(n^2) passes but is the naive version.

Think about it first

Hint 1 Which single node's identity can you read off immediately from the `postorder` array?
Hint 2 Once you know the root, find it in `inorder`. That index splits `inorder` into the exact left-subtree values and right-subtree values β€” and the left subtree's *size* tells you how to split `postorder` too.
Hint 3 Recurse: build the root from the end of `postorder`, then recursively build right and left subtrees. To reach `O(n)`, precompute a value→index hash map for `inorder` and consume `postorder` from the back (build the **right** subtree before the left).
Your workspace Not runnable by design β€” this is your interview scratchpad. Saved on this device.