LeetCode105/106/889 Construct Binary Tree from Pre/In/Post Order Tranversal
- Construct Binary Tree from Preorder and Inorder Traversal
all we need to remeber is: for any tree in preorder tranverse, no matter if it a whole tree or subtree, the first element will always be the root.
and based on this, we divide the elements in in order tranverse to get all elements of left and right subtree.
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return helper(0, 0, inorder.length - 1, preorder, inorder); //why don't we use preEnd? because, those infomation will hide in inStart or inEnd
}
private TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { //preStart points the position of current root
//two connor cases: if preStart pointer reached the end,
if (preStart >= preorder.length) {
return null;
}
//or inStart met the inEnd
if (inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(preorder[preStart]);//like I said, this is the root
int inIndex = 0; //iterate to get the index of current root in inorder array
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
inIndex = i; //so inIndex will divide inorder[inStart, inEnd] into two parts, and so we can do recusrsion
}
}
root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder);
root.right = helper(preStart + (inIndex - inStart + 1), inIndex + 1, inEnd, preorder, inorder);
return root;
}
}
- Construct Binary Tree from Inorder and Postorder Traversal
compare to the previous problem, they seems just the same, except, this time, the end element of tree or subtree in postorder, is the root node.
the code is bascially the same, just need to remeber that each time we need to know the length we need to move to relocate the postEnd pointer. just use a base case to get those length.
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return helper(postorder.length - 1, 0, inorder.length - 1, inorder, postorder);
}
private TreeNode helper(int postEnd, int inStart, int inEnd, int[] inorder, int[] postorder) {
if (postEnd < 0) {
return null;
}
if (inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(postorder[postEnd]);
int inIndex = inStart; //indicates the divide point in inorder tranverse
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
inIndex = i; //
break;
}
}
root.left = helper(postEnd - (inEnd - inIndex + 1), inStart, inIndex - 1, inorder, postorder);
root.right = helper(postEnd - 1, inIndex + 1, inEnd, inorder, postorder);
return root;
}
}
- Construct Binary Tree from Preorder and Postorder Traversal
so we know that the first element of preorder is the root of any tree or subtrees. and the last element of postorder is the root of any tree or subtrees. and the rest of them is the left subtree and right subtree based on current root. but how can we make sure the left part and right part?
well, whether the represention of our tree is preorder or postorder, the elements contains in left tree or right tree of a fixed root will always be the same, just the order of these element in array will be different.
for example:
Input: pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
so first step is to extract root, which is 1.
[2,4,5,3,6,7],
[4,5,2,6,7,3] will be left.
so we initialize i and j pointer to these two partial array. and i and j will move forward by 1 step each time, until the first, we have a situation of: pre[start, i] is the anotamy of post[start, j]. so this part will be left subtree, and the remaining will be right subtree.
however, check those two subarray is antomy or not is pretty time consuming, we can’t simply just add them. I mean, the ways we can check if two subarrays are antomy are: use hashmap, which is good in current situtation since everytime i and j pointer moves, it can update easily. but how do we compare two hashmaps? Or we can use presort, and check if they contains the same elements.
but all those things seems less effective.
so thanks to the solution provided by @lee215 from Leetcode, we have a way better solution:
Create a node TreeNode(pre[preIndex]) as the root.
Becasue root node will be lastly iterated in post order,
if root.val == post[posIndex],
it means we have constructed the whole tree,
If we haven’t completed constructed the whole tree,
So we recursively constructFromPrePost for left sub tree and right sub tree.
And finally, we’ll reach the posIndex that root.val == post[posIndex].
We increment posIndex and return our root node.
and the code is:
class Solution {
int preIndex = 0, posIndex = 0;
public TreeNode constructFromPrePost(int[]pre, int[]post) {
TreeNode root = new TreeNode(pre[preIndex++]);
if (root.val != post[posIndex])
root.left = constructFromPrePost(pre, post);
if (root.val != post[posIndex])
root.right = constructFromPrePost(pre, post);
posIndex++;
return root;
}
}
it’s a confusing code. we will discuss it later.

浙公网安备 33010602011771号