Given inorder and postorder traversal of a tree, construct the binary tree.
Analysis
This problem can be illustrated by using a simple example.
in-order: 4 2 5 (1) 6 7 3 8 post-order: 4 5 2 6 7 8 3 (1)
From the post-order array, we know that last element is the root. We can find the root in in-order array. Then we can identify the left and right sub-trees of the root from in-order array.
Using the length of left sub-tree, we can identify left and right sub-trees in post-order array. Recursively, we can build up the tree.
For this example, the constructed tree is:
Java Solution
public TreeNode buildTree(int[] inorder, int[] postorder) { int inStart = 0; int inEnd = inorder.length - 1; int postStart = 0; int postEnd = postorder.length - 1; return buildTree(inorder, inStart, inEnd, postorder, postStart, postEnd); } public TreeNode buildTree(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) { if (inStart > inEnd || postStart > postEnd) return null; int rootValue = postorder[postEnd]; TreeNode root = new TreeNode(rootValue); int k = 0; for (int i = 0; i < inorder.length; i++) { if (inorder[i] == rootValue) { k = i; break; } } root.left = buildTree(inorder, inStart, k - 1, postorder, postStart, postStart + k - (inStart + 1)); // Becuase k is not the length, it it need to -(inStart+1) to get the length root.right = buildTree(inorder, k + 1, inEnd, postorder, postStart + k- inStart, postEnd - 1); // postStart+k-inStart = postStart+k-(inStart+1) +1 return root; } |
why are we using two functions with varying parameters,what would be the output if only first function is used.
int k = 0;
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == rootValue) {
k = i;
break;
}
}
i should be = to instart and not 0.
A solution for the case where duplicated values are admitted.
Note: I used sub list for clarity may/should be changed to indexed “sublists” for efficiency.
TreeNode reconstruct(List inOrder, List postOrder) {
int rootValue = postOrder.get(postOrder.size() - 1);
TreeNode root = new TreeNode(rootValue);
for (int i = 0; i 0) {
TreeNode left =
reconstruct(inOrder.subList(0, i), postOrder.subList(0, postOrder.size() - rightSize - 1));
if (left == null) continue; //wasn't the root what we found
root.left = left;
}
if (rightSize > 0) {
TreeNode right =
reconstruct(
inOrder.subList(i + 1, inOrder.size()),
postOrder.subList(postOrder.size() - rightSize - 1, postOrder.size() - 1));
if (right == null) continue; //wasn't the root what we found
root.right = right;
}
return root; //both subtrees succeeded
}
}
return null;
}
This code is working only if all elements are unique, But I tried this method on the following:
int[] inorder = {4,1,5,1,6,7,3,8};
int[] postorder = {4,5,1,6,7,8,3,1};
I got this error Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: -1
Arrays.asList does not work as expected for primitives, only Objects. that change would give you the wrong answer
Nice.
Just some suggestions for more readable code:
1. use inclusive start index and exclusive end index. [start, end) so that you don’t need hairy +1 and -1.
2.give these expressions a name: postStart+k-(inStart+1); postStart+k-inStart.
int k=0;
for(int i=0; i< inorder.length; i++){
if(inorder[i]==rootValue){
k = i;
break;
}
}
can be simplified as
int k = java.util.Arrays.asList(inorder).indexOf(rootValue)
what if the binary tree has duplicates?
Isnt
postStart+k-(inStart+1) will always be k-1?
this is BT, but not necessarily BST
in-order: 4 2 5 (1) 6 7 3 8
is this correct inorder as left subtree element of 1 are greater than 1. Left Subtree should be lesser
The for loop “for(int i=0; i< inorder.length; i++){" can be simplified to "for(int i = inStart; i <= inEnd; ++i){" in case duplicated