Problem
Given two integer arrays preorder
and inorder
where preorder
is the preorder traversal of a binary tree and inorder
is the inorder traversal of the same tree, construct and return the binary tree.
Examples
Example 1:
3
/ \
9 20
/ \
15 7
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
Similar Problems
Construct Binary Tree from Inorder and Postorder Traversal Construct Binary Tree from Inorder and Level Order Traversal
Solution
Method 1 - Recursion
Lets look at the binary tree:
1
/ \
2 3
/ \ / \
4 5 6 7
The inorder and preorder traversal are:
inorder = [4, 2, 5, 1, 6, 3, 7]
preorder = [1, 2, 4, 5, 3, 6, 7]
How does preorder[]
array helps?
The first element in preorder[]
acts as the root of the tree (in this case, 1).
How does inorder[]
array helps?
inorder[]
helps determine the left and right subtrees of the root. Elements appearing before the root in inorder[]
belong to the left subtree, while elements appearing after belong to the right subtree. In our case, it is [4, 2, 5]
on left and [6, 3, 7]
on right. (See picture below).
See this step above and recursively construct left subtree and link it root.left and recursively construct right subtree and link it root.right.
Code
Java
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0 || inorder.length == 0 || preLength != inLength) {
return null;
}
int preLength = preorder.length;
int inLength = inorder.length;
return helper(preorder, inorder, 0, 0, inLength - 1);
}
private static TreeNode helper(int[] preorder, int[] inorder, int preStart, int inStart, int inEnd) {
if (inStart > inEnd || preStart > preorder.length - 1) {
return null;
}
// Pick current node from Preorder traversal using preStart and increment preStart
TreeNode root = new TreeNode(preorder[preStart]);
// If this node has no children then return
if (inStart == inEnd) {
return root;
}
// Else find the index of this node in Inorder traversal
int inIndex = linearSearch(inorder, root.val, inStart, inEnd);
// Using index in Inorder traversal, construct left and right subtrees
root.left = helper(preorder, inorder, preStart + 1, inStart, inIndex - 1);
// We are skipping the elements on the left of the current pre order node by adding inIndex - inStart + 1
root.right = helper(preorder, inorder, preStart + inIndex - inStart + 1, inIndex + 1, inEnd);
return root;
}
static int linearSearch(int[] arr, int value, int start, int end) {
for (int i = start; i <= end; i++) {
if (arr[i] == value) {
return i;
}
}
return -1;
}