题目:从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
答案:
递归
先序遍历序列中,第一个结点必为根节点;中序遍历序列被根节点分为两部分:根结点之前的部分为左子树结点中序序列,根结点之后的为右子树结点中序序列。
所以,通过先序序列确定根节点,通过寻找根节点在中序序列的位置,确定左右子树的长度(设中序序列根节点之前的部分的长度lLen,则先序序列根节点之后的lLen个结点属于左子树,再之后的部分属于右子树)
函数返回子树的根节点
例如:已知一棵二叉树的先序序列为EBADCFHG,中序序列为ABCDEFGH,则下图说明还原二叉树的过程:
首先由先序序列知道二叉树的根节点为E,则其左子树的中序序列为(ABCD),右子树的中序序列为(FGH)。反过来知道二叉树左子树的先序序列为(BADC),右子树先序序列为(FHG)。然后对二叉树的左右子树分别用先序和中序序列分析其根节点及其左右子树,直到得到整个二叉树结构。
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildBinTree(preorder,inorder,0,0,preorder.length);
}
//preIndex表示先序序列开始位置,inIndex表示中序序列开始位置,len表示序列长度
private TreeNode buildBinTree(int[] preorder, int[] inorder, int preIndex, int inIndex, int len) {
if(len > 0){
int lLen = 0;
TreeNode root = new TreeNode(preorder[preIndex]);
for(int i = inIndex; i < inorder.length; i++) {
if(inorder[i] == preorder[preIndex]) {
break;
}
lLen++;
}
root.left = buildBinTree(preorder,inorder,preIndex+1,inIndex,lLen);
root.right = buildBinTree(preorder,inorder,preIndex+1+lLen,inIndex+1+lLen,len-1-lLen);
return root;
}
return null;
}
}