面试题07. 重建二叉树

重建二叉树

题目描述

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


示例:

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



提示:
0 <= 节点个数 <= 5000

转载来源:力扣(LeetCode)


题目分析

众所周知:

  • 先序遍历的首先遍历的是根节点,所以先序遍历结果的第一个值是根节点的值
  • 中序遍历先遍历的是根节点的左子树,接着是根节点的值,再是根节点的右子树,所以中序遍历根节点的值左边的是根节点的左子树中序遍历结果,右边是右子树的中序遍历结果

根据上面的两个基本知识,这道题就基本差不多了:

  1. 根据[3,9,20,15,7],可以知道这棵树的根节点是3
  2. 根据[9,3,15,20,7],找到根节点的位置,可以知道左子树为[9],右子树为[15,20,7]
  3. 序列[9]回到1,构建出节点3的左子树,序列[15,20,7]回到1,构建出节点3的右子树
  4. 返回结果

我的做法是遍历中序数组去寻找根节点的位置,所以时间复杂度是O(N*LogN),看了题解,发现大牛们使用HashMap<TreeNode,Integer>来存放数组,实现了O(1)的寻找节点,所以他们做法的时间复杂度是O(N),但是算法的思路适合我上面的一样的,我就不贴他们的代码了。下面是我的代码:

    private int[] preorder;
    private int[] inorder;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder.length == 0)
            return null;
        this.preorder = preorder;
        this.inorder = inorder;
        return buildTree(0, preorder.length - 1, 0, preorder.length - 1);
    }

    private TreeNode buildTree(int headPreOrder, int tailPreOrder, int headInOrder, int tailInOrder) {
        if (headPreOrder < 0 || tailPreOrder >= preorder.length || headPreOrder > tailPreOrder)
            return null;
        if (headInOrder < 0 || tailInOrder >= preorder.length || headInOrder > tailInOrder)
            return null;
        if (headPreOrder == tailPreOrder)
            return new TreeNode(preorder[headPreOrder]);
//      先序遍历里的第一个就是头结点
        TreeNode root = new TreeNode(preorder[headPreOrder]);

//      找出头结点在中序遍历的位置,从而得到左子树和右子树
        int headInInorderIndex = 0;
        for (int i = headInOrder; i <= tailInOrder; i++) {
            if (preorder[headPreOrder] == inorder[i]) {
                headInInorderIndex = i;
                break;
            }
        }
//      左子树里的节点的个数
        int leftSize = headInInorderIndex - headInOrder;
        root.left = buildTree(headPreOrder + 1, headPreOrder + leftSize, headInOrder, headInInorderIndex - 1);
        root.right = buildTree(headPreOrder + leftSize + 1, tailPreOrder, headInInorderIndex + 1, tailInOrder);
        return root;
    } 

代码文件


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例...
    编程小王子AAA阅读 77评论 0 0
  • 树形结构 在前面章节中介绍到的数据结构,都为线性结构,比如链表,数组,队列等,都属于线性结构,类似于通过一根线串在...
    ducktobey阅读 1,309评论 0 0
  • 二叉树 1 二叉树简介 二叉树是树的特殊一种,具有如下特点: 1、每个结点最多有两颗子树,结点的度最大为2。2、左...
    孔雨露阅读 956评论 0 2
  • 本文首发于我的个人博客:尾尾部落 0. 几个概念 完全二叉树:若二叉树的高度是h,除第h层之外,其他(1h-1)层...
    繁著阅读 3,201评论 3 49
  • 前言 二叉树的前序遍历,中序遍历,后序遍历是面试中常常考察的基本算法,关于它的概念这里不再赘述了,还不了解的同学可...
    Jesse1995阅读 16,646评论 0 3