根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
题解:
- 这题以前复习考研在王道上做过,以为自己理解了,今天实际做的时候发现并不简单
- 原理:由于中序序列的特殊性----左子树一定在当前节点的左侧且右子树一定在当前节点的右侧,故中序+前序/后序 均可以构造一颗二叉树
- 步骤:1、在前序中依次取节点root,在中序中寻找root_inorder_index,此位置将中序划分为两段,左边为root的左子树,右边为root的右子树,递归返回root 。 2、root选取的顺序应当和preorder的元素顺序一致,由于前序遍历是visit--->left----->right,所以递归也需按照此顺序进行,且在每次进入递归前,pos指向下一个preoreder位置保持一致
- 中序序列中左闭右开序列,[left,right),右侧right是不在选取范围内的,如left==right为 [left,left)为空集
class Solution {
//当前preorder中元素索引
int pos = 0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
//遍历前序序列,紧跟在前序序列后的,查看在中序序列中index大小判断为左子树还是右子树
if(preorder.length == 0){
return null;
}
return build(preorder, inorder, 0 , inorder.length);
}
TreeNode build(int[] pre,int[] in,int left, int right){
//中序序列中左闭右开序列,[left,right),right位置不应该被选到
// left==right为 [left,left)为空集
if(left == right){
return null;
}
TreeNode root = new TreeNode(pre[pos]);
int root_val = pre[pos];
//依次在preorder中寻找下一个元素作为递归的下一个root,递归顺序与前序序列保持一致
pos++;
int inIndex = getIndex(in,root_val);
//右侧inIndex应递增,但是对于左闭右开序列,[left,right),右侧inIndex是不在选取范围内的
root.left = build(pre,in,left,inIndex);
//左侧inIndex已经被选过,故递增+1
root.right = build(pre,in,inIndex+1,right);
return root;
}
int getIndex(int[] array, int target){
//可用HashMap存放 key=pre_val, val=in_index;省略重复查找
for(int i=0 ; i<array.length ; i++){
if(target==array[i]){
return i;
}
}
return -1;
}
}