给定一棵树的前序遍历与中序遍历,依据此构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 = [3,9,20,15,7] 中序遍历 = [9,3,15,20,7]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
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
preorder = [3,9,20,15,7] inorder = [9,3,15,20,7]
Return the following binary tree:
3 / \ 9 20 / \ 15 7
个人思路:
前序遍历序列的第一个元素一定是该树的根节点,因而从此入手,在中序遍历序列中找到该元素,其左所有元素都是以该元素为根节点的左子树的节点,其右所有元素都是以该元素为根节点的右子树的节点,可在此将两边分为左子树和右子树的中序遍历子序列两个新的数组。同时,前序遍历序列中根节点之后的节点都是先把左子树节点遍历完毕才遍历右子树节点的,因此可以根据中序遍历序列中左子树节点的数量,找到所有属于左子树和右子树的元素,并分为两个新的前序遍历子序列数组。然后利用递归分别对左右子树的前序和中序序列进行处理,如果序列为空则返回null,如果序列只有一个值则可判断为叶子节点,返回当前节点。最终可得到一个完整的二叉树。
代码(JavaScript):
/**
* 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.length==0||inorder.length==0){
return null;
}
TreeNode result = new TreeNode(preorder[0]);
if(preorder.length==1){
return result;
}
int top_pos=0;
for(top_pos=0;top_pos<inorder.length;top_pos++){
if(inorder[top_pos]==preorder[0]){
break;
}
}
int[] left_preorder=new int[top_pos];
int[] left_inorder=new int[top_pos];
int[] right_preorder=new int[preorder.length-top_pos-1];
int[] right_inorder=new int[preorder.length-top_pos-1];
for(int i=0;i<top_pos;i++){
left_preorder[i]=preorder[i+1];
left_inorder[i]=inorder[i];
}
result.left=buildTree(left_preorder,left_inorder);
for(int i=0;i<preorder.length-top_pos-1;i++){
right_preorder[i]=preorder[i+top_pos+1];
right_inorder[i]=inorder[i+top_pos+1];
}
result.right=buildTree(right_preorder,right_inorder);
return result;
}
}