leetcode刷题-重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

重建二叉树

上午在学习广度遍历优先的算法,看到可以通过该算法层级遍历二叉树,于是想写个二叉树来测试一下算法,刚好算法群的群主很灵性,今天就发了这么一道打卡题,真是[一箭双雕」,美滋滋。

前序,中序,后序

简单说一下二叉树的遍历方式,按照根节点的遍历顺序不同,可以分为三种

  • 前序,根节点->左节点->右节点
  • 中序,左节点->根节点->右节点
  • 后序,左节点->右节点->根节点

可以参照例题中的二叉树验证一下各种遍历方式。

如何确认二叉树

给定一个二叉树,我们能确定它的前序,中序,后序的遍历序列;反过来,给定前序,中序,后序中的一个,能否确认一个二叉树,答案是:不能。

因为要倒推出一个二叉树,至少需要:

  • 确认根节点
  • 左,右子树的节点情况

至少需要给定两个遍历序列才能确认二叉树,并且不是随意两个序列的组合

  • 前序 and 中序,满足上述条件
  • 中序 and 后序,满足上述条件
  • 前序 and 后续,不满足上述条件

例题中举的二叉树例子,我们试着来推导一下

根据前序遍历的规则,我们可以确认首个元素是根节点,再根据根节点在中序中的位置去推断左右子树的元素

接着我们需要来写出推算公式,画到这里突然发现我举的这个例子不太直观,这边借用一下 leetcode 大佬画的图(这个画图软件是他推荐给我的,叫做 omnigraffle,逼格非常高)

由上图我们可知:

  • 通过 [preL + 1, pivot - inL + preL] , [inL, pivot - 1] 两个区间,可以递归往下确认左子树
  • 通过 [pivot - inL + preL + 1, preR] ,[pivot + 1, inR] 两个区间,可以递归往下确认右子树

实现代码如下:

class Node {
    public int value;
    public Node left;
    public Node right;

    public Node(int val) {
        value = val;
    }
}


public class BinaryTree {
    Node root;
    int[] preOrder;
    HashMap<Integer, Integer> inOrderMap = new HashMap<>();

    public Node buildTree(int[] preorder, int[] inorder) {
        this.preOrder = preorder;

        // 存储中序中元素的索引位置,方便后续查找根节点索引不用重复遍历
        for (int i = 0; i < inorder.length; i++) {
            inOrderMap.put(inorder[i], i);
        }

        this.root = buildTree(0, preOrder.length - 1, 0, inorder.length - 1);
    }

    public Node buildTree(int preL, int preR, int inL, int inR) {
        if (preL > preR || inL > inR) return null;
        
      Node root = new Node(preOrder[preL]);

        // 计算根节点在中序中的位置
        int pivotIndex = inOrderMap.get(root.value);

        // 构造左子树
        root.left = buildTree(preL + 1, pivotIndex - inL + preL, inL, pivotIndex - 1);
        // 构造右子树
        root.right = buildTree(pivotIndex - inL + preL + 1, preR, pivotIndex + 1, inR);

        return root;
    }
题目链接

https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值