Construct Binary Tree from Preorder and Inorder Traversal
重建二叉树
Given preorder and inorder traversal of a tree, construct the binary tree.
考虑:前序遍历的第一个元素即为根节点的值,然后在中序遍历中找到该元素,则位于其前的为左子树的中序遍历,位于其后的为右子树的中序遍历。同理,前序遍历中第一个元素后先是左子树的前序遍历,然后是右子树的前序遍历。根据这个特点,用递归的方法实现二叉树的重建。
注意这道题,如果想减小运行时间,在递归过程中尽量传递原数组中各子树遍历的序号,而不是构建新的数组进行传递。下面两种解法,一种为传递数组,一种为传递序号,均AC但时间不同。
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 && inorder.length == 0)
return null;
TreeNode root = new TreeNode(preorder[0]);
int flag = -1;
for(int i=0;iif(inorder[i] == root.val){
flag = i;
break;
}
}
int[] newInorderLeft = new int[flag];
int[] newPreorderLeft = new int[flag];
int[] newInorderRight = new int[inorder.length-flag-1];
int[] newPreorderRight = new int[preorder.length-flag-1];
for(int i=0;ifor(int i=0;i1];
}
for(int i=0;i1;i++){
newInorderRight[i] = inorder[flag+1+i];
}
for(int i=0;i1;i++){
newPreorderRight[i] = preorder[flag+1+i];
}
root.left = buildTree(newPreorderLeft,newInorderLeft);
root.right = buildTree(newPreorderRight, newInorderRight);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length == 0 && inorder.length == 0)
return null;
return helper(0, 0, inorder.length - 1, preorder, inorder);
}
public TreeNode helper(int preStart, int inStart,
int inEnd, int[] preorder, int[] inorder) {
if (preStart >= preorder.length || inStart > inEnd)
return null;
TreeNode root = new TreeNode(preorder[preStart]);
int flag = -1;
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
flag = i;
break;
}
}
root.left = helper(preStart + 1, inStart, flag - 1, preorder, inorder);
//注意对于右子树的前序遍历,开始的序号要减去其中序遍历开始的序号,防止溢出, 即 flag + 1 - inStart 为右子树针对此时的根节点的位移量。
root.right = helper(preStart + flag + 1 - inStart, flag + 1, inEnd, preorder, inorder);
return root;
}