Construct Binary Tree from Preorder and Inorder Traversal
问题:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
解决:
【解析】对于下面的这棵树:
红色是根节点,蓝色为左子树,绿色为右子树。
可以发现的规律是:
1. 先序遍历的从左数第一个为整棵树的根节点。
2. 中序遍历中根节点是左子树右子树的分割点。
① 给定先序遍历结果和中序遍历结果,构造一棵二叉树。采用递归的方式解决该问题:
a) 通过先序遍历找到第一个点作为根节点,在中序遍历中找到根节点并记录index;
b) 因为中序遍历中根节点左边为左子树,所以可以记录左子树的长度并在先序遍历中依据这个长度找到左子树的区间,用同样方法可以找到右子树的区间。
c) 递归的建立好左子树和右子树就好。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution { //18ms
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
return buildTree(preorder,0,preLen - 1,inorder,0,inLen - 1);
}
public TreeNode buildTree(int[] preorder,int preStart,int preEnd,int[] inorder,int inStart,int inEnd){
if(preStart > preEnd || inStart > inEnd){
return null;
}
int rootVal = preorder[preStart];
int rootIndex = 0;
for (int i = inStart;i <= inEnd ;i ++ ) {
if(inorder[i] == rootVal){
rootIndex = i;
break;
}
}
int llen = rootIndex - inStart;
TreeNode root = new TreeNode(rootVal);
root.left = buildTree(preorder,preStart + 1,preStart + llen,inorder,inStart,rootIndex - 1);
root.right = buildTree(preorder,preStart + llen + 1,preEnd,inorder,rootIndex + 1,inEnd);
return root;
}
}
② 在discuss中看到的,从两边向中间查找。
class Solution { //1ms
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder,0,inorder,0,inorder.length - 1);
}
public TreeNode buildTree(int[] preorder,int preStart,int[] inorder,int inStart,int inEnd){
if(inStart > inEnd){
return null;
}
TreeNode root = new TreeNode(preorder[preStart]);
int rootIndex = -1;
for (int k = inStart,l = inEnd;k <= l ;k ++,l -- ) {//从两边向中间查找根节点
if(inorder[k] == root.val) {
rootIndex = k;
break;
} else if(inorder[l] == root.val) {
rootIndex = l;
break;
}
}
root.left = buildTree(preorder,preStart + 1,inorder,inStart,rootIndex - 1);
root.right = buildTree(preorder,preStart + rootIndex - inStart + 1,inorder,rootIndex + 1,inEnd);
return root;
}
}