剑指Offer:重建二叉树

题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

牛客网给出的准备代码如下:

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        
    }
}

作者:Monotone
链接https://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6
来源:牛客网
递归思想,每次将左右两颗子树当成新的子树进行处理,中序的左右子树索引很好找,前序的开始结束索引通过计算中序中左右子树的大小来计算,然后递归求解,直到startPre>endPre||startIn>endIn说明子树整理完到。方法每次返回左子树活右子树的根节点

下面是我结合理解,给出的解释。

思想:这道题运用到了递归方法。首先,要知道前序遍历和中序遍历结果倒推二叉树的步骤(可以看我的这篇文章前序遍历、中序遍历、后序遍历)。主要步骤就是,先确定根结点,再确定左结点和右结点。这个就是需要我们递归的步骤。那么在题目中,确定根结点是很好确定的,但是左结点和右节点就有难度,因为左右都是子树而不是叶子结点。那么我们就把左右子树都重新当成新的树来处理,重复上述步骤(确定根结点,在确定左、右结点)。

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode tree = reConstruct(pre,0,pre.length-1,in,0,in.length-1);
        return tree;
    }
   
    public TreeNode reConstruct(int[] pre,int startPre,int endPre,int[] in,int startIn,int endIn){
        if(startPre>endPre || startIn>endIn){//递归结束的条件
            return null;
        }
        TreeNode root = new TreeNode(pre[startPre]);//每次将根结点确定
        for(int i=startIn;i<=endIn;i++){
            if(in[i] == pre[startPre]){//找到根结点在中序遍历结果数组的位置
            	//在中序遍历结果中找到根结点后root后,以root为分界线,分为左子树的值集合和右子树的值集合(因为在中序遍历结果中,根结点的左边属于它的左子树里的值,右边属于它的右子树里的值)
                root.left = reConstruct(pre,startPre+1,startPre+i,in,startIn,i-1);
                root.right = reConstruct(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
                break;
            }
        }
        return root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值