Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
Copy preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
Analysis
关键在于Preorder中[root, left, right]的遍历顺序和Inorder的[left, root, right]顺序。因此可以从preorder中得到root ,在inorder中找到对应的root ,于是left和right子树就可以分别进行进一步查找。
Solution
Copy /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree ( int [] preorder , int [] inorder) {
if (preorder == null || inorder == null || preorder . length != inorder . length ) {
return null ;
}
return buildTreeHelper(preorder , inorder , 0 , preorder . length - 1 , 0 , inorder . length - 1 ) ;
}
TreeNode buildTreeHelper ( int [] preorder , int [] inorder , int preStart , int preEnd , int inStart , int inEnd) {
if (inStart > inEnd) {
return null ;
}
int rootPosition = findPosition(inStart , inEnd , inorder , preorder[preStart]) ;
TreeNode root = new TreeNode(preorder[preStart]) ;
root . left = buildTreeHelper(preorder , inorder , preStart + 1 , preStart + rootPosition - inStart , inStart , rootPosition - 1 ) ;
root . right = buildTreeHelper(preorder , inorder , preEnd - inEnd + rootPosition + 1 , preEnd , rootPosition + 1 , inEnd ) ;
return root;
}
int findPosition ( int start , int end , int [] arr , int target) {
int i;
for (i = start; i <= end; i ++ ) {
if (arr[i] == target) {
return i;
}
}
return - 1 ;
}
}
Using Pre-built Hashmap for Index Lookup
via @yavinci : use HashMap to cache the inorder[] position.
Copy public TreeNode buildTree( int [] preorder , int [] inorder) {
Map < Integer , Integer > inMap = new HashMap < Integer , Integer >();
for ( int i = 0 ; i < inorder . length ; i ++ ) {
inMap . put (inorder[i] , i);
}
TreeNode root = buildTree(preorder , 0 , preorder . length - 1 , inorder , 0 , inorder . length - 1 , inMap) ;
return root;
}
public TreeNode buildTree( int [] preorder , int preStart , int preEnd , int [] inorder , int inStart , int inEnd , Map< Integer , Integer > inMap) {
if (preStart > preEnd || inStart > inEnd) return null ;
TreeNode root = new TreeNode(preorder[preStart]) ;
int inRoot = inMap . get ( root . val );
int numsLeft = inRoot - inStart;
root . left = buildTree(preorder , preStart + 1 , preStart + numsLeft , inorder , inStart , inRoot - 1 , inMap) ;
root . right = buildTree(preorder , preStart + numsLeft + 1 , preEnd , inorder , inRoot + 1 , inEnd , inMap) ;
return root;
}
*LeetCode Official Solution
Depth First Search (DFS) - Recursion - ID Map
Copy class Solution {
// start from first preorder element
int pre_idx = 0 ;
int [] preorder;
int [] inorder;
HashMap < Integer , Integer > idx_map = new HashMap < Integer , Integer >();
public TreeNode helper ( int in_left , int in_right) {
// if there is no elements to construct subtrees
if (in_left == in_right)
return null ;
// pick up pre_idx element as a root
int root_val = preorder[pre_idx];
TreeNode root = new TreeNode(root_val) ;
// root splits inorder list
// into left and right subtrees
int index = idx_map . get (root_val);
// recursion
pre_idx ++ ;
// build left subtree
root . left = helper(in_left , index) ;
// build right subtree
root . right = helper(index + 1 , in_right) ;
return root;
}
public TreeNode buildTree ( int [] preorder , int [] inorder) {
this . preorder = preorder;
this . inorder = inorder;
// build a hashmap value -> its index
int idx = 0 ;
for ( Integer val : inorder) {
idx_map . put (val , idx ++ );
}
return helper( 0 , inorder . length ) ;
}
}
Reference
https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/