Construct Binary Tree from In-order and Level-order traverse
Jeff posted on (updated on )
Question
You are given two array, in
, which contains the result of the in-order traverse of a binary tree, and level
which contains the result of the level-order traverse of a binary tree. Return the original binary tree.
Algorithm
Find the root by taking the first element from level-order array, then construct new in-order array for left and right sub tree, and construct new level order array for left and right sub tree as well.
To generate in-order traverse, simply take the elements that are to the left/right of the root value.
To generate level-order traverse, take only the elements from the parent level-order array that are present in the in-order array for sub tree.
Then recursively generate the left & right sub tree.
Solution
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Main {
TreeNode solution(int[] in, int[] level) {
if (in == null || in.length == 0) {
return null;
}
TreeNode root = new TreeNode(level[0]);
int[] inLeft = buildInOrderForLeftSubTree(in, root.val);
root.left = solution(
inLeft,
buildLevelOrder(level, inLeft)
);
int[] inRight = buildInOrderForRightSubTree(in, root.val);
root.right = solution(
inRight,
buildLevelOrder(level, inRight)
);
return root;
}
int indexOf(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i;
}
}
return -1;
}
// return the elements in `in` array that are on the left side of root
int[] buildInOrderForLeftSubTree(int[] in, int root) {
int idxRoot = indexOf(in, root);
if (idxRoot == 0) {
return null;
}
int[] ans = new int[idxRoot];
for (int i = 0; i < idxRoot; i++) {
ans[i] = in[i];
}
return ans;
}
// return the elements in `in` array that are on the right side of root
int[] buildInOrderForRightSubTree(int[] in, int root) {
int idxRoot = indexOf(in, root);
if (idxRoot == (in.length - 1)) {
return null;
}
int[] ans = new int[in.length - idxRoot - 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = in[idxRoot + 1 + i];
}
return ans;
}
int[] buildLevelOrder(int[] level, int[] in) {
if (in == null) {
return null;
}
// build set
Set<Integer> set = new HashSet<>();
for (int each : in) {
set.add(each);
}
// generate new level-order array, containing elements that are in `in` array only
int[] ans = new int[set.size()];
int idx = 0;
for (int each : level) {
if (set.contains(each)) {
ans[idx++] = each;
}
}
return ans;
}
public static void main(String[] args) {
Main main = new Main();
TreeNode root = main.solution(new int[]{4, 8, 10, 12, 14, 20, 22}, new int[]{20, 8, 22, 4, 12, 10, 14});
System.out.println(root.val);
}
}