2023-09-24  阅读(1)
原文作者:moxiaolin 原文地址: https://blog.csdn.net/qq_37909508/article/details/89372250

题目描述

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

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

做这道题之前一定要对前序遍历和中序遍历非常理解,刚开始由于我没有很好的理解他们,画图的时候一直卡着,差点以为是题目的例子错了,不过后来很好,看了朋友画的图反应过来了;

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

这道题主要是你得有node的结点意识,每个点往下层又是一个root结点;以这种思想然后进行递归,问题就很好解决了;

首先对例子进行分析:

前序遍历序列{1,2,4,7,3,5,6,8}

中序遍历序列{4,7,2,1,5,3,8,6}

这里面你首先根据前序遍历可知道root结点是1,然后又根据中序遍历你可以知道1左边的都是root根结点的左孩子群{4,7,2},1右边的都是root根结点的右孩子群{5,3,8,6};

根据上面我们可以画出第一个结点:

202309242322506471.png

这样你可以先进入root根结点的左孩子群里面;root(1)的左孩子是2,在这里你就得把左孩子直接看成一个root根结点,其他的暂时都不用想,这样的话,以root根结点来看它的:

前序遍历序列{2,4,7}

中序遍历序列{4,7,2}

这里面你又根据前序遍历可知道root结点是2,然后根据中序遍历你可以知道2左边的都是root(2)根结点的左孩子群,2右边没有,说明没有右孩子群;

根据上面我们可以画出第二个结点:

202309242322534222.png

你又进入到root(2)的左孩子群里面,以4作为根结点继续:

前序遍历序列{4,7}

中序遍历序列{4,7}

以4做为root(4)结点,根据中序遍历发现它没有左孩子只有一个右孩子,那么在这里开始遍历它的右子树,得出它俩如下的位置:

202309242322552153.png

回到上一个的右子树群,一直追溯回去发现,也就只剩下是root(1)的右子树没有遍历了,然后直接又以右子树建立前序遍历和中序遍历:

前序遍历序列{3,5,6,8}

中序遍历序列{5,3,8,6}

根据前序遍历的性质,以root(3)为根结点,由中序遍历可知3左边的{5}为左孩子群,{8,6}为右孩子群;现在可以又可以确定一个结点:

202309242322563344.png

以root(3)为根简单分析它的左孩子群:

前序遍历序列{3,5}

中序遍历序列{5,3}

根据中序遍历可知5是root(3)的左孩子,root(3)没有右孩子,又可以画出一个结点:

202309242322573215.png

由于root(5)已经没有左孩子和右孩子了,又回到root(3)分析它的右孩子:

前序遍历序列{6,8}

中序遍历序列{8,6}

根据前序遍历root(6)为根结点,根据中序遍历root(6)左边的为左孩子群,右边的为右孩子群(很显然它没有右孩子群)

202309242322583606.png

进入root(6)的左孩子群,直接得出左孩子结点为8,画出最终图像:

202309242322593287.png

下面贴出代码:

    /**
     * Definition for binary tree
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    import java.util.*;
    public class Solution {
        public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
            if(pre.length==0||in.length==0) {
    			return null;
    		}
    		TreeNode node=new TreeNode(pre[0]);
    		if(pre.length==1||in.length==1) {
    			return node;
    		}
    		for(int i=0;i<pre.length;i++) {
    			if(pre[0]==in[i]) {
    				node.left=reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1),Arrays.copyOfRange(in, 0, i));
    				node.right=reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length),Arrays.copyOfRange(in, i+1, in.length));
    			}
    		}
    		return node;
        }
    }

理解上面解题的思维,程序其实并不难,只是几行代码加上两个递归;对于二叉树一定要以结点的思想去思考,这样会更容易理解.


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文