剑指 Offer 07. 重建二叉树

一、题目 

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例 1:

        Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
        Output: [3,9,20,null,null,15,7]
示例 2:

        Input: preorder = [-1], inorder = [-1]
        Output: [-1]

限制:0 <= 节点个数 <= 5000

二、思路

 首先通过遍历找到根节点、进而确定该根节点的左右子树,再分别确定左、右子树的根节点。依次递归。当根节点没有左右子树的时,结束递归。

画图找一下规律:

1、前序遍历的第一个节点是根节点、进而将中序遍历结果分为两份左右两颗树,得到根节点是3;

2、再由左子树的前序遍历结果(9)确定左子树的根节点为9,

        右子树的前序遍历结果(20、15、7),得到右子树的根节点为20;

3、由中序遍历结果:此时根节点为9的左子树已经没有左右子树。根节点为20的右子树再分为两部分:左子树15、右子树7;

4、依次递归,直至根节点没有左右子树。

三、代码

    //    全局哈希表,
    HashMap<Integer, Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
//        判断是否为空
        if(preorder==null||preorder.length<=0){
            return null;
        }
        for (int i = 0; i < inorder.length; i++) {
//            给中序遍历做映射
            map.put(inorder[i],i);
        }
        TreeNode root = f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);

        return root;

    }

       TreeNode f(int[] preorder ,int l1,int r1,int[] intorder,int l2,int r2){
    //        递归出口
           if(l1>r1&&l2>r2){
               return null;
           }
    //        获取根节点:前序遍历的第一个节点
           TreeNode root = new TreeNode(preorder[l1]);
    //       获取根节点的下标
           int i =map.get(preorder[l1]);
    //       递归处理左子树
           root.left =f(preorder,l1+1,l1+(i-l2),intorder,l2,i-1);
    //       递归处理右子树
           root.right=f(preorder,l1+(i-l2)+1,r1,intorder,i+1,r2);
           return root;
       }

运行结果:

四、总结

二叉树前序遍历:先遍历根节点、再遍历左子树、最后遍历右子树。(根左右)

二叉树中序遍历:先遍历左子树、再遍历根节点、最后遍历右子树。(左根右)

二叉树后序遍历:先遍历左子树、再遍历右子树、最后遍历根节点。(左右根)

三种遍历的递归代码只需要调整代码的顺序即可。迭代代码需要用到辅助栈。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值