文章目录

  • 一、二叉树的重建
    • (一)面试题07. 重建二叉树
    • (二)分析该题目
    • (三)java代码实现
    • (四)IDEA调试代码,详细查看构建的过程
    • (五)附Arrays.copyOfRange()的用法
  • 二、小郑有话说

一、二叉树的重建

在LeetCode中有这么一道算法题:《重建二叉树》

(一)面试题07. 重建二叉树

面试题07. 重建二叉树

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

例如,给出

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

返回如下的二叉树:

    3/ \9  20/  \15   7

限制:

0 <= 节点个数 <= 5000

(二)分析该题目

从题目中可以看到,给出了两个数组,一个书前序遍历二叉树得出的结果,一个是中序遍历二叉树得出的结果。

利用这两个结果,来还原出一颗二叉树。

首先你要知道什么是前序遍历和中序遍历。你还要知道,给你一颗二叉树,使用这些遍历的算法怎么得到遍历的结果,不然是没办法继续完成重建二叉树的。

如果你还不输入二叉树的遍历,可以看这篇文章:
《我是怎么一步一步调试出来二叉树的遍历(超精彩配图),二叉树遍历再也不用愁了》

先来看一下前序遍历

如下图所示,前序遍历就是:

再来看一下中序遍历:

终须遍历则是:

最终就得到的这样的数组:

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

如果你够细心的话,会发现前序遍历的第一个是3,而这个3就整颗二叉树的根节点;

在看一下中序的结果:

如下图所示,如果我们把中序中3所在的位置的左右两部分分割开,就得到了根节点3的所有左边和右边的节点。

[9],[3],[15,20,7]

不难发现,如果我们以此类推的话,就可以还原出一颗二叉树。

(三)java代码实现

package tree;import java.util.Arrays;/*** @Auther: truedei* @Date: 2020 /20-6-9 12:00* @Description: 二叉树重建*/
public class Solution {/*** 根据前序和中序遍历的二叉树的结果构建二叉树* @param preorder  前序遍历结果的数组* @param inorder   中序遍历结果的数组* @return  返回一个构建好的二叉树*/static public TreeNode buildTree(int[] preorder, int[] inorder) {if(preorder==null || preorder.length==0)return null;//1,获取树的根节点的value值TreeNode root = new TreeNode(preorder[0]);//2,查找每一次根节点在中序遍历结果中的位置int index = findIndex(preorder[0],inorder);//3,构建left左子树
//        root.left = buildTree(左子树前序数组,左子树中序数组)root.left = buildTree(Arrays.copyOfRange(preorder,1,index + 1 ),Arrays.copyOfRange(inorder,0,index));//4,构建reght右子树
//        root.right=buildTree(右子树前序数组,右子树中序数组)root.right = buildTree(Arrays.copyOfRange(preorder,index+1,preorder.length),Arrays.copyOfRange(inorder,index+1,inorder.length));return root;}/*** 查找根的index(在中序中的位置)的函数* @param preorderData 节点* @param inorder 每一次的中序数组* @return 索引位置*/static  public int findIndex(int preorderData, int[] inorder){for (int i = 0; i < inorder.length; i++) {if(inorder[i]==preorderData)return i;}return 0;}public static void main(String[] args) {TreeNode treeNode = buildTree(new int[]{3,9,20,15,7}, new int[]{9,3,15,20,7});theFirstTraversal(treeNode);}//先序遍历 用于测试最终的结果是否正确public static void theFirstTraversal(TreeNode root) {System.out.println(root.val);if (root.left != null) {  //使用递归进行遍历左孩子theFirstTraversal(root.left);}if (root.right != null) {  //递归遍历右孩子theFirstTraversal(root.right);}}
}

核心代码:

用于递归构建二叉树

 /*** 根据前序和中序遍历的二叉树的结果构建二叉树* @param preorder  前序遍历结果的数组* @param inorder   中序遍历结果的数组* @return  返回一个构建好的二叉树*/static public TreeNode buildTree(int[] preorder, int[] inorder) {if(preorder==null || preorder.length==0)return null;//1,获取树的根节点的value值TreeNode root = new TreeNode(preorder[0]);//2,查找每一次根节点在中序遍历结果中的位置int index = findIndex(preorder[0],inorder);//3,构建left左子树
//        root.left = buildTree(左子树前序数组,左子树中序数组)root.left = buildTree(Arrays.copyOfRange(preorder,1,index + 1 ),Arrays.copyOfRange(inorder,0,index));//4,构建reght右子树
//        root.right=buildTree(右子树前序数组,右子树中序数组)root.right = buildTree(Arrays.copyOfRange(preorder,index+1,preorder.length),Arrays.copyOfRange(inorder,index+1,inorder.length));return root;}/*** 查找根的index(在中序中的位置)的函数* @param preorderData 节点* @param inorder 每一次的中序数组* @return 索引位置*/static  public int findIndex(int preorderData, int[] inorder){for (int i = 0; i < inorder.length; i++) {if(inorder[i]==preorderData)return i;}return 0;}

一定有十万个为什么,为什么要这样写,其实写法有很多。接下来咱们一起来调试一下,看看执行时是什么样子的。

(四)IDEA调试代码,详细查看构建的过程

我这里使用的工具是IDEA。

为了方便调试,便于查看每一次执行的结果,我们先打上断点。

然后Debug运行此java文件,如下图所示,就是最初运行的结果

进一步了解一下:

可以看到现在传入的前序数组和中序数组分别为:

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

一定要有印象哦

下图就是看到的我们接着上一个图下一步之后的结果。

在这个操作了,我们起作用的是TreeNode root = new TreeNode(preorder[0]);

我们拿到了前序数组0号位置的数据,至于为什么一定要拿到前序数组中的0号位置的数据,可以看一下下面的图。解释的很清楚了。

下一步之后,就会看到下面的结果;

这里我们要去查找拿到的3在中序数组中的所在的位置

至于为什么,请看下图

这里就不在说明Arrays.copyOfRange()的作用了,请看(五)附Arrays.copyOfRange()的用法,给大家准备好了。

接下来就要使用拿到的index,去构建一个左节点了

继续下一步

继续下一步

继续下一步

开始构造3右边所有的节点:

这样我们就拿到了20的左节点

现在就可以构造出最后一个节点了,不过因为是顺序执行的,所以省略n步

验证是否正确:

到此为止,结束了。

经过Debug一遍,心里一定很清晰了。

(五)附Arrays.copyOfRange()的用法

与使用System.arraycopy进行数组复制类似的, Arrays提供了一个copyOfRange方法进行数组复制

Arrays.copyOfRange()的格式如下:

  1. 第一个参数表示源数组
  2. 第二个参数表示开始位置(取得到)
  3. 第三个参数表示结束位置(取不到)
copyOfRange(int[] original, int from, int to)

实例代码:

import java.util.Arrays;
public class HelloWorld {public static void main(String[] args) {int a[] = new int[] { 18, 62, 68, 82, 65, 9 };// 不同的是System.arraycopy,需要事先准备好目标数组,并分配长度。// copyOfRange只需要源数组就就可以了,通过返回值,就能够得到目标数组了。// 除此之外,需要注意的是 copyOfRange 的第3个参数,表示源数组的结束位置,是取不到的。// copyOfRange(int[] original, int from, int to)// 第一个参数表示源数组// 第二个参数表示开始位置(取得到)// 第三个参数表示结束位置(取不到)int[] b = Arrays.copyOfRange(a, 0, 3);for (int i = 0; i < b.length; i++) {System.out.print(b[i] + "\t");//18    62    68}// 溢位复制System.out.println();int[] C = Arrays.copyOfRange(a, 0, 7);for (int i = 0; i <C.length; i++) {System.out.print(C[i] + "\t");//18    62    68    82    65    9    0}}
}

这里参考地址:

Java基础学习——复制数组の——Arrays.copyOfRange()方法讲解

二、小郑有话说

如果对你有帮助,可以分享给你身边的朋友。或者给俺点个大大的赞和大大的评论点赞评论就是给我最大的支持,感谢。
水平有限,难免会有疏漏或者书写不合理的地方,欢迎交流讨论。
作者:TrueDei
作者唯一博客CSDN:https://truedei.blog.csdn.net/
转载说明:如需转载请注明原地址和作者名。

如果喜欢我的文章,还没看够可以关注我,我会用心写好每一篇文章。

欢迎大佬们加入在下的小社,在此大家可以放开的交流,共同学习进步:

客官、点个赞再走吧

手把手教你如何重建二叉树(超精彩配图)相关推荐

  1. 二叉树为空意味着二叉树_我是怎么调试出来二叉树的遍历(超精彩配图),从此遍历不再愁了...

    推荐学习 牛掰!"基础-中级-高级"Java程序员面试集结,看完献出我的膝盖 数据结构与算法,程序员必过的坎?不掌握一定挤不进BATJ的神技? 我是怎么调试出来二叉树的遍历(超精彩 ...

  2. 华为语音解锁设置_华为手机免费语音转文字功能如何开启?手把手教你如何设置,超赞...

    原标题:华为手机免费语音转文字功能如何开启?手把手教你如何设置,超赞 关于华为手机免费语音转文字功能,相信你也有所了解,但还有很大部份华为手机用户表示:我的手机为什么没有语音转文字的功能. 如果你是华 ...

  3. 手把手教你运行YOLOv6(超详细)

    YOLOv6 是美团视觉智能部研发的一款目标检测框架,致力于工业应用.本框架同时专注于检测的精度和推理效率,在工业界常用的尺寸模型中:YOLOv6-nano 在 COCO 上精度可达 35.0% AP ...

  4. 实战案例,手把手教你使用 Tableau 绘制超炫酷可视化图表

    有一种美叫数据的美,Tableau可以让你看到这种数据美,以及探索数据美的可能,如下图表均是由强大的tableau可视化而成的. 喜欢点赞.收藏 使用tableau的优势就在于不需要懂技术,更不需要写 ...

  5. 手把手教你下载VS2022(超详细)

    目录 一.下载 二.安装配置 一.下载 来到下载网址后,我们如下图所示点击Community 2022下载即可,是社区免费版. VS2022下载链接 (去官网下载即可哦,不需要去某些需要收费的网站,就 ...

  6. 手把手教你用ECharts画柱状图

    导读:柱状图主要用于表示离散数据的频数,也是一种基础可视化图. 作者:王大伟 来源:大数据DT(ID:hzdashuju) 01 简单的柱状图 在ECharts中制作柱状图也十分简单,通过将serie ...

  7. 我的世界服务器显示器,我的世界红石显示器制作教程 手把手教你做显示器

    我的世界红石显示器制作教程 手把手教你做显示器.那下面给大家分享的是我的世界里面的一个红石显示器的制作教程,那对下面的这个显示器感兴趣的玩家不妨进来卡看哦!希望大家喜欢. 游戏园我的世界官方群:325 ...

  8. python numpy安装教程_手把手教你搭建机器学习开发环境—Python与NumPy的超简安装教程...

    手把手教你搭建机器学习开发环境Python语言是机器学习的基础,所以,想要入门机器学习,配置好Python的开发环境是第一步.本文就手把手的教你配置好基于Python的机器学习开发环境.超简单!第一步 ...

  9. 超详细深度学习debug指南,国外小哥手把手教你如何调试模型 | 附PPT

    晓查 发自 凹非寺 量子位 出品 | 公众号 QbitAI 已经学会深度学习,但你搭建的模型为什么还跑不动,到底哪里出了问题? 看懂了教材,一到编程调试就跪,为了寻找bug的你是否曾经手足无措? 虽然 ...

最新文章

  1. 科略教育——执行力的3W管理法
  2. 【Android 应用开发】Android游戏音效实现
  3. Visual Studio 2017 ASP.NET Core开发
  4. 设置clion执行前的cmake命令,和CMAKELIST.txt不冲突
  5. 工具类集和_gblfy版本
  6. 哪些高级感中文Logo字体可免费商用?
  7. 五分钟告诉你什么是爬虫?
  8. Java多线程系列--【JUC集合07】- ArrayBlockingQueue
  9. 服务器白屏维修,液晶屏故障汇总及检修方法之一(白屏)
  10. Solidworks篮球建模
  11. 史鉴使人明智;诗歌使人巧慧;数学使人精细;博物使人深沉;伦理之学使人庄重;逻辑与修辞使人善辩
  12. Java抽象类和接口使用_Java 抽象类和接口
  13. ps绘制android手机界面界面,教程·Photoshop | 手机界面效果图展示设计
  14. win7安装Winpcap4.12显示An error occurred while installing the NPF diver(0x00000430).
  15. 关于Java自己记不住和不知道的知识点
  16. android 精简rom,推荐稳定精简ROM【Android 4.1.1-CM10-3.1.10】(8月25日)
  17. 电商系统需求分析手册
  18. sybase安装步骤
  19. C# .net用法大全
  20. 更猛更持久的广告投放,闲鱼程序员的年终奖全靠它。。。

热门文章

  1. @+id/和android:id有什么区别?
  2. 【Bugly干货分享】微信文件微起底Ⅰ
  3. 怎么解决Win7看视频绿屏的问题?
  4. android tv 和手机,Android TV 设计
  5. 微信智能相框来了,这次能抄底吗?
  6. php微信静默授权获取头像,【微信】未关注公众号授权获取基本信息(头像昵称等)...
  7. android 双卡识别,Android 双卡双待识别
  8. Android中打招呼
  9. NC6单据动作约束开发过程
  10. 关于CSS中关于定位的总结