AlgoMaster Logo

Construct Binary Tree from Preorder and Inorder Traversal

Last Updated: April 1, 2026

medium
4 min read

Understanding the Problem

We have two arrays that describe the same binary tree from different perspectives. Preorder traversal visits root, then left subtree, then right subtree. Inorder traversal visits left subtree, then root, then right subtree.

The question is: can we combine these two perspectives to uniquely reconstruct the original tree? The answer is yes, and the reasoning is elegant.

The preorder array always tells us the root first. But preorder alone cannot tell us where the left subtree ends and the right subtree begins (unlike a BST where values give us that split). That is where inorder comes in. Once we know the root, we can find it in the inorder array, and everything to its left in inorder belongs to the left subtree, everything to its right belongs to the right subtree. This gives us the split point we need.

So the two traversals complement each other perfectly: preorder identifies the root, and inorder tells us the subtree boundaries.

Key Constraints:

  • 1 <= preorder.length <= 3000 → With n up to 3000, an O(n^2) approach runs at most ~9 million operations, which is fine. But we can do O(n) with a hash map optimization.
  • -3000 <= preorder[i], inorder[i] <= 3000 → Values can be negative. No impact on the algorithm, but good to note.
  • All values are unique → This is crucial. It means we can locate any value in the inorder array unambiguously. Without uniqueness, the problem would be ambiguous.

Approach 1: Recursion with Linear Search

Intuition

The most natural approach comes from understanding what each traversal tells us.

Preorder gives us the root immediately, it is always the first element. But it does not tell us where the left subtree ends and the right subtree begins. In a BST, the values themselves tell us this (everything smaller goes left), but in a general binary tree, we cannot rely on that.

This is where inorder comes in. Once we know the root value from preorder, we can find it in the inorder array. Everything to the left of the root's position in inorder belongs to the left subtree, and everything to the right belongs to the right subtree. This is exactly by definition of inorder traversal: left, root, right.

Here is the really useful part: once we know the left subtree has, say, k nodes (from the inorder split), we also know the next k elements in the preorder array after the root form the left subtree's preorder. The remaining elements form the right subtree's preorder.

So we recursively apply the same logic: pick the root from preorder, find it in inorder to get the split, and recurse on both halves.

Algorithm

  1. If the current range is empty (no elements to process), return null.
  2. Take the first element in the current preorder range as the root.
  3. Scan the inorder array to find this root's position.
  4. The number of elements to the left of the root in inorder gives us the left subtree size.
  5. Recursively build the left subtree using the appropriate slices of preorder and inorder.
  6. Recursively build the right subtree using the remaining slices.
  7. Return the root with its left and right children attached.

Example Walkthrough

1Root = preorder[0] = 3
0
root
3
1
9
2
20
3
15
4
7
1/5
1Find root=3 in inorder: index 1
0
9
1
root=3
3
2
15
3
20
4
7
1/5
1Create root node 3
3root
1/5

Code

This approach works correctly, but for every node we create, we scan the inorder array to find the root's position. What if we pre-computed every value's position so lookups were O(1)?

Approach 2: Recursion with Hash Map (Optimal)

Intuition

The algorithm from Approach 1 is fundamentally correct. The only thing slowing it down is the linear search to find the root in the inorder array. If we could look up any value's index in O(1), each recursive call would do O(1) work, and the total time would drop to O(n).

A hash map is the perfect tool for this. Before we start building the tree, we iterate through the inorder array once and map each value to its index. Then during recursion, finding the root's position in inorder becomes a single hash map lookup instead of a scan.

Everything else stays the same: preorder tells us the root, inorder (via the hash map) tells us the split, and we recurse on both halves.

Algorithm

  1. Build a hash map mapping each value in inorder to its index.
  2. Start the recursive build with the full range of both arrays.
  3. At each step, take the first element in the current preorder range as the root.
  4. Look up the root's index in the inorder array using the hash map (O(1)).
  5. Calculate the left subtree size from the inorder split.
  6. Recursively build the left subtree, then the right subtree.
  7. Return the constructed root.

Example Walkthrough

1Build hash map from inorder. Root = preorder[0] = 3
0
root
3
1
9
2
20
3
15
4
7
1/5
1Lookup root=3: map[3]=1 (O(1) instead of linear scan)
3
:
1
7
:
4
9
:
0
15
:
2
20
:
3
1/5
1Create root node 3
3root
1/5

Code