剑指Offer-04.重建二叉树

重建二叉树

题目

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

思路

1. 递归

抓住核心找根节点
综合上面的介绍树的遍历方式,我们发现前序遍历的第一个节点必然是这棵树的根节点。而在中序遍历中,由于其特殊的访问顺序规则根节点总是在中间,处于根节点左边则是左子树的节点集合,而处于根节点右边则是右子树的节点集合。所以我们根据根节点找出左右子树后,又可以对左右子树按照同样的思路来处理。因此此处采用递归非常合适。
下面我们结合例子,简单复述一下上面的处理过程。
前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}。

  1. 根据前序遍历的第一个节点,我们可以知道这课树的根节点为1.
  2. 然后我们在中序遍历中找到我们的根节点1所处的位置,position = 3
  3. 我们得出根节点1的左子树节点集合为{4,7,2}。右子树的节点集合为{5,3,8,6}
  4. 接下来我们处理左子树,同样根据前序遍历可知左子树集合4,7,2的根节点为2,因为树的前序遍历的第一个节点必为根节点呀。
  5. 然后我们在中序遍历中找到我们的根节点2所处的位置,position = 2
  6. 我们得出根节点2的左子树节点集合为{4,7}。右子树的节点集合为为空,说明该节点没有右子树。
  7. 之后我们继续按如下的操作的处理左子树集合{4,7}
    ………

按照以上步骤,最终就会重构出我们的二叉树。这里可以发现只要子树的区间大小变为0了,说明父节点没有对应的子树,因此就不必继续递归处理,而是开始回溯。还有一点,我们是按照先左后右的递归处理,所以前序遍历中的每次都是按顺序去取来作为根节点的。所以可以用一个全局的index来控制前序的访问位置即可。我们只需关注中序遍历中每次划分的区间大小即可。

public class Solution {

    static int index;

    public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        index = 0; //必须加这行,否则会失败,是答题系统问题?  index  初始化不是0吗?
        int len = pre.length;
        return reConstructBinaryTree(pre, in, 0, len - 1);
    }

    public static TreeNode reConstructBinaryTree(int[] pre, int[] in, int s, int e) {
        TreeNode treeNode = null;
        if (s <= e) {
            treeNode = new TreeNode(pre[index]);
            int i = getiByVal(pre[index++], in, s, e);
            treeNode.left = reConstructBinaryTree(pre, in, s, i - 1);
            treeNode.right = reConstructBinaryTree(pre, in, i + 1, e);
        }
        return treeNode;
    }

   
    public static int getiByVal(int val, int[] in, int s, int e) {
        for (int i = s; i <= e; i++) {
            if (val == in[i]) {
                return i;
            }
        }
        return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值