剑指offer系列之四:重建二叉树

简介:

题目描述

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

在完成代码之前,我自己分析了一下如何根据前序遍历和中序遍历的结果构建一棵二叉树。首先,根据二叉树遍历的性质,由前序遍历的结果序列可知该二叉树的根节点是1,在根据中序遍历的结果可是根节点1的左子树包含的结点是4、7、2,右子树包含的节点是5、3、8、6。现在考虑左子树中节点4、7、2,由于这三个节点在前序遍历的结果是2、4、7,那么2必然是这三个节点组成的子树的根节点,再回到中序遍历的结果4、7、2,那么可以判断出4是2的左孩子,7是4的右孩子;同理可以对右子树进行判断。这样,画出的二叉树是这样的:

构建的二叉树

自然,我们可以分析判断过程写出构建二叉树的完整代码:

package com.rhwayfun.offer;

public class ConstructBinaryTree {

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        return constructCore(pre,0,pre.length - 1,in,0,in.length - 1);
    }

    private TreeNode constructCore(int[] pre,int startPreOrder, int endPreOrder, int[] in,int startInOrder, int endInOrder) {
        //根据前序遍历找到根节点的值
        int rootValue = pre[startPreOrder];
        TreeNode rootNode = new TreeNode(rootValue);
        rootNode.left = null;
        rootNode.right = null;

        //只有一个结点,那么该节点就是根节点,直接返回
        if(startPreOrder == endPreOrder){
            if(startInOrder == endInOrder && pre[startPreOrder] == in[startInOrder]){
                return rootNode;
            }
        }

        //根据中序遍历的结果找到根节点
        int rootOfInOrder = startInOrder;
        while(rootOfInOrder <= endInOrder && in[rootOfInOrder] != rootValue){
            rootOfInOrder++;
        }

        //异常处理
        if(rootOfInOrder == endInOrder && in[rootOfInOrder] != rootValue){
            return null;
        }

        //计算左子树的长度
        int leftSubTreeLen = rootOfInOrder - startInOrder;
        //根据左子树的长度计算前序遍历结果中左子树的最后一个结点的下标
        int leftIndexOfPreOrderEnd = startPreOrder + leftSubTreeLen;
        //重建左子树
        if(leftSubTreeLen > 0){
            rootNode.left = constructCore(pre, startPreOrder + 1, leftIndexOfPreOrderEnd, in, startInOrder, rootOfInOrder - 1);
        }
        //重建右子树
        if(leftSubTreeLen < endPreOrder - startPreOrder){
            rootNode.right = constructCore(pre, leftIndexOfPreOrderEnd + 1, endPreOrder, in, rootOfInOrder + 1, endInOrder);
        }
        return rootNode;
    }

    public static void main(String[] args) {
        int[] pre = {1,2,4,7,3,5,6,8};
        int[] in = {4,7,2,1,5,3,8,6};
        TreeNode root = new ConstructBinaryTree().reConstructBinaryTree(pre, in);
        System.out.println(root);
    }
}
AI 代码解读
目录
打赏
0
0
0
0
85
分享
相关文章
喔嚯霍,二叉树的遍历,先序,中序,后序原来这么简单(附代码)!!!
喔嚯霍,二叉树的遍历,先序,中序,后序原来这么简单(附代码)!!!
|
10月前
【一刷《剑指Offer》】面试题 6:重建二叉树
【一刷《剑指Offer》】面试题 6:重建二叉树
【力扣·每日一题】1036. 逃离大迷宫 (C++ bfs 思维)
【力扣·每日一题】1036. 逃离大迷宫 (C++ bfs 思维)
114 0
【力扣·每日一题】1036. 逃离大迷宫 (C++ bfs 思维)
【数据结构与算法】第十二章:线索化二叉树
在二叉树的一些应用中,常常要求在数中查找具有某种特征的结点,或者是对树中的全部结点逐一进行处理,这就提出了一个遍历二叉树的问题。本章将详细介绍二叉树的存储和遍历。
202 0
【力扣·每日一题】429. N 叉树的层序遍历(C++ bfs)
【力扣·每日一题】429. N 叉树的层序遍历(C++ bfs)
128 0
重温算法之二叉树的锯齿形层序遍历
关于二叉树的题目其实是我的弱项,虽然二叉树不是很难理解,但是从学校开始接触二叉树开始就对它不是很感冒,所以很多时候都避开它,但是再难咬的骨头也的得啃,二叉树运用在很多程序的底层实现里,比如MySQL的索引实现就是B+树,我们懂得使用索引的同时也得知道,索引为什么这么快,而其快的原因就是底层里B+树得实现。
125 0
重温算法之二叉树的锯齿形层序遍历
NowCoder刷题(1)【树】二叉树的遍历(含图解)
NowCoder刷题(1)【树】二叉树的遍历(含图解)
NowCoder刷题(1)【树】二叉树的遍历(含图解)
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等