Problem
Given a inorder and level order traversal, construct a binary tree from that.
Examples
Example 1:
3
/ \
9 20
/ \
15 7
Input: levelorder = [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 Preorder Traversal Construct Binary Tree from Inorder and Postorder Traversal
Solution
Method 1 - Recursion
Lets look at the binary tree:
1
/ \
2 3
/ \ / \
4 5 6 7
The inorder and level-order traversal are:
inorder = [4, 2, 5, 1, 6, 3, 7]
levelOrder = [1, 2, 4, 5, 3, 6, 7]
How does levelOrder[]
array helps?
Elements in levelOrder[]
give us levels to us, and we can start adding those elements in the tree.
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.
The algorithm starts by identifying the root (last element) from the level-order traversal. Then, it finds the inorder index i
of the root element. Elements to the left (left subtree) and right (right subtree) of i in the inorder traversal are used to construct new arrays, newLeftLevel
and newRightLevel
, by extracting corresponding elements from the level-order traversal while maintaining their sequence. Finally, recursive calls are made to construct the left and right subtrees using these new arrays.
(See picture below).
Code
Java
class Solution {
public TreeNode buildTree(int[] inorder, int[] levelOrder) {
// Call the recursive function with full arrays and return the result
return buildTree(inorder, levelOrder, 0, inorder.length - 1);
}
public TreeNode buildTree(int[] inorder, int[] levelOrder, int iStart, int iEnd) {
if (iStart > iEnd) {
return null;
}
int rootVal = levelOrder[0];
TreeNode root = new Node(rootVal);
if (iStart == iEnd) {
return root;
}
int index = findIndex(inorder, rootVal, iStart, iEnd);
int[] newleftLevel = newLevelOrder(inorder, levelOrder, iStart, index - 1);
int[] newrighttLevel = newLevelOrder(inorder, levelOrder, index + 1, iEnd);
root.left = buildTree(inorder, newleftLevel, iStart, index - 1);
root.right = buildTree(inorder, newrighttLevel, index + 1, iEnd);
return root;
}
public int[] newLevelOrder(int[] inorder, int[] levelOrder, int iStart, int iEnd) {
int[] newlevel = new int[iEnd - iStart + 1];
int x = 0;
for (int i = 0; i < levelOrder.length; i++) {
if (findIndex(inorder, levelOrder[i], iStart, iEnd) != -1) {
newlevel[x] = levelOrder[i];
x++;
}
}
return newlevel;
}
public int findIndex(int[] inorder, int value, int iStart, int iEnd) {
int x = -1;
for (int i = iStart; i <= iEnd; i++) {
if (value == inorder[i]) {
x = i;
}
}
return x;
}
}