剑指offer 07. 重建二叉树( 前序、中序、后序,知二求一)

1. 题目描述

2.解题思路

题目分析:

  • 前序遍历特点: 节点按照 [ 根节点 | 左子树 | 右子树 ] 排序,以题目示例为例:[ 3 | 9 | 20 15 7 ]
  • 中序遍历特点: 节点按照 [ 左子树 | 根节点 | 右子树 ] 排序,以题目示例为例:[ 9 | 3 | 15 20 7 ]
  • 根据题目描述输入的前序遍历和中序遍历的结果中都不含重复的数字,其表明树中每个节点值都是唯一的。

思路:

  1. 前序遍历的第一个数就是根节点root
  2. 在中序遍历中找到root对应的位置,可以求出root的左子树和右子树分别对应哪些节点
  3. 然后再对左右子树进行递归,每次递归可以确定三个节点的关系。

递归解析:

  • 先根据前序遍历找到根节点对应的索引 pre_root
  • 然后根据pre_root的值,在中序遍历中找到对应数的索引 index
    1. root = new TreeNode(po[pre_root]) ;
    2. root.left  = 向左递归
    3. root.right = 向右递归
    4. 递归结束的条件是,in_left > in_right,返回null,说明下面没有节点了
  • 树构建的过程:一直向左递归,先构建最左边的三个节点的子树,然后返回上一层,再将该子树看作一个节点,继续完成三个“节点”子树的创建,知道递归调用结束,返回最开始的root,构建出一个完整的树。
 

3. 代码

class Solution {

    HashMap<Integer,Integer> map = new HashMap();//装入的是中序遍历数组中,值对应的下标,方便查找,无需多次遍历中序数组

    int[] po;  //和前序遍历的数组一模一样
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        po = preorder;
        //初始化map
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i],i);
        }
        return recur(0,0,inorder.length -1);
    }

    //递归函数,传入构建子树的根节点和左右边界
    TreeNode recur(int pre_root, int in_left, int in_right){
        if(in_left > in_right){
            return null;
        }
        //根据索引获取值,构建根节点
        TreeNode root = new TreeNode(po[pre_root]);
        //找到该值对应的中序数组下标
       int index =  map.get(root.val);
       //向左进行遍历
       root.left = recur(pre_root + 1,in_left,index - 1);
       root.right = recur(pre_root + index - in_left + 1,index + 1,in_right);
       return root;
    }
}

4. 测试结果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值