由前序遍历和中序遍历重建二叉树

唯一的难点就是确定当前节点的左子树的根节点和右子树的根节点分别在前序遍历数组的位置。例如

先序遍历数组pre:1 2 3 4 5 6 7
中序遍历数组in: 3 2 4 1 6 5 7

1是当前根节点,它在pre中的位置

pre_start = 0

接着在in中找到1的位置,即分割点

j = 3

当前树根所囊括的in数组范围是

in_start = 0;
in_end = in.length-1;

将in按j分割后,3 2 4就是其左子树部分,6 5 7就是其右子树部分。那么左子树和右子树的根节点是哪个呢?根节点是由先序遍历数组确定的。

在pre数组中,注意到,左子树的根节点就是当前根节点的下一个,即

root_left = pre_start + 1

而右子树的根节点需要在当前根节点pre_start的基础上向前移动j-in_start+1个位置,到达右子树的部分,这部分的第一个元素就是右子树的根节点了:

root_right = pre_start + j - in_start + 1

所以,代码如下:

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if (pre.length==0) return null;
        return construct(pre, in, 0, 0, in.length-1);
    } 

    private TreeNode construct(int[] pre, int[] in, 
            int pre_start,
            int in_start, int in_end) {
        if(in_start>in_end) return null;
        if(in_start==in_end) return new TreeNode(pre[pre_start]);
        TreeNode son = new TreeNode(pre[pre_start]);
        int j = in_start;
        while(in[j]!=pre[pre_start]) j++;
        // Find the root respectively for left part and right part      
        son.left = construct(pre, in, pre_start+1, in_start, j-1);
        son.right = construct(pre, in, pre_start+j-in_start+1, j+1, in_end);
        return son;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值