坚持刷题|重建二叉树

文章目录

  • 题目
  • 考察点
  • 代码实现
  • 实现总结
  • 扩展问题
    • 从前序和中序遍历中序列构建二叉树
      • 题目
      • 代码实现
      • 与后序实现的异同点
    • 前序和后序可不可以唯一确定一棵二叉树呢?

Hello,大家好,我是阿月。坚持刷题,老年痴呆追不上我,今天刷:重建二叉树

题目

106. 从中序与后序遍历序列构造二叉树
在这里插入图片描述

考察点

不仅考察了对数据结构和算法的理解,还考察了如何将理论知识转化为实际的代码实现,并且需要考虑算法的效率和优化:

  • 二叉树的遍历:需要理解中序遍历和后序遍历的概念,并知道它们的应用场景和特点。
  • 递归:在构造二叉树的过程中,需要使用递归算法来处理子树。
  • 数组操作:需要熟练地对数组进行索引和切片操作,以便在中序和后序遍历序列中定位根节点和子树的范围。
  • 二叉树的构造:理解如何根据中序遍历和后序遍历序列构造二叉树,包括根据根节点在中序遍历中的位置将树分割成左右子树,并且根据后序遍历序列确定左右子树的范围。
  • 时间复杂度分析:在实现算法时需要考虑其时间复杂度,尤其是递归算法的时间复杂度分析,以确保算法的效率。

代码实现

class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;}
}public class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {if (inorder == null || postorder == null || inorder.length != postorder.length) {return null;}return buildTreeHelper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);}private TreeNode buildTreeHelper(int[] inorder, int inStart, int inEnd,int[] postorder, int postStart, int postEnd) {if (inStart > inEnd || postStart > postEnd) {return null;}int rootValue = postorder[postEnd];TreeNode root = new TreeNode(rootValue);int rootIndex = 0;for (int i = inStart; i <= inEnd; i++) {if (inorder[i] == rootValue) {rootIndex = i;break;}}int leftTreeSize = rootIndex - inStart;root.left = buildTreeHelper(inorder, inStart, rootIndex - 1,postorder, postStart, postStart + leftTreeSize - 1);root.right = buildTreeHelper(inorder, rootIndex + 1, inEnd,postorder, postStart + leftTreeSize, postEnd - 1);return root;}public static void main(String[] args) {Solution solution = new Solution();int[] inorder = {9, 3, 15, 20, 7};int[] postorder = {9, 15, 7, 20, 3};TreeNode root = solution.buildTree(inorder, postorder);// 在这里可以添加遍历树的代码来验证结果}
}

实现总结

  • 首先通过后序遍历的最后一个节点找到根节点的值,然后根据中序遍历序列将其分割成左子树和右子树,接着根据后序遍历序列确定左子树和右子树的范围,最后递归构造左子树和右子树即可。
  • 时间复杂度
  • 递归
    • 递归函数返回值以及参数:
      • 返回值:重建好的二叉树。
      • 参数:中序遍历序列,中序的开始坐标,中序的结束坐标,后序遍历序列,后序的开始坐标,后序的结束坐标。
    • 终止条件:
      • 如果中序遍历或者后序遍历的开始坐标大于结束坐标(inStart > inEnd || postStart > postEnd),也就是数组大小为零,说明是空节点,直接返回。
    • 单层递归逻辑:
      • 通过后序遍历找到根节点的值。
      • 根据根节点的值将中序遍历分割为左子树和右子树。
      • 根绝中序遍历切割的左子树和右子树size对后序遍历进行左右子树范围切割。
  • 时间复杂度:O(n^2)。
    • 首先,在每个节点的递归调用中,需要在中序遍历序列中搜索根节点的位置。这个操作的时间复杂度是 O(n),因为在最坏的情况下,可能需要遍历整个中序遍历序列来找到根节点的位置。
    • 然后,对每个节点都会进行递归操作。在最坏情况下,每个节点都需要处理一次,因此总的时间复杂度是 O(n)。
    • 总体来说,这个算法的时间复杂度是 O(n^2)。

扩展问题

从前序和中序遍历中序列构建二叉树

题目

105. 从前序与中序遍历序列构造二叉树
在这里插入图片描述

代码实现

class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;}
}public class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder == null || inorder == null || preorder.length != inorder.length) {return null;}return buildTreeHelper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}private TreeNode buildTreeHelper(int[] preorder, int preStart, int preEnd,int[] inorder, int inStart, int inEnd) {if (preStart > preEnd || inStart > inEnd) {return null;}int rootValue = preorder[preStart];TreeNode root = new TreeNode(rootValue);int rootIndex = 0;for (int i = inStart; i <= inEnd; i++) {if (inorder[i] == rootValue) {rootIndex = i;break;}}int leftTreeSize = rootIndex - inStart;root.left = buildTreeHelper(preorder, preStart + 1, preStart + leftTreeSize,inorder, inStart, rootIndex - 1);root.right = buildTreeHelper(preorder, preStart + leftTreeSize + 1, preEnd,inorder, rootIndex + 1, inEnd);return root;}public static void main(String[] args) {Solution solution = new Solution();int[] preorder = {3, 9, 20, 15, 7};int[] inorder = {9, 3, 15, 20, 7};TreeNode root = solution.buildTree(preorder, inorder);// 在这里可以添加遍历树的代码来验证结果}
}

与后序实现的异同点

  • 异:
    • 根节点的确定:
      • 在前序遍历中,根节点总是序列的第一个元素。
      • 在后序遍历中,根节点总是序列的最后一个元素。
    • 子树的顺序划分:
      • 在前序遍历中,左子树的元素紧随着根节点之后,而右子树的元素在左子树元素之后,具有明显的顺序。
      • 在后序遍历中,右子树的元素位于根节点之前,而左子树的元素位于右子树之前,同样具有明显的顺序。
  • 同:
    • 从前序和中序遍历序列构建二叉树的递归过程和从后序和中序遍历序列构建二叉树的递归过程在本质上是相似的。

前序和后序可不可以唯一确定一棵二叉树呢?

  • 前序和后序不能唯一确定一棵二叉树。
  • 前序和中序可以唯一确定一棵二叉树,后序和中序可以唯一确定一棵二叉树,是因为他们都有中序遍历确定左右子树部分。
  • 前序和后序没有中序遍历无法确定左右部分,也就是无法分割,无法确定唯一的一棵二叉树。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468326.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年危险化学品生产单位安全生产管理人员证考试题库及危险化学品生产单位安全生产管理人员试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品生产单位安全生产管理人员证考试题库及危险化学品生产单位安全生产管理人员试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&a…

Solidworks:剖切模型

剖切模型可以看清模型内部。今天设计了一个模型&#xff0c;试验一下如何剖切。 操作很方便&#xff0c;只需要点击一下零件模型上方的剖切按钮&#xff0c;立即就转入剖切视图。剖切后结果如下。 工程图纸中也可以展示剖面视图&#xff0c;操作方法是点击工程图工具页中的“…

Python教程57:海龟画图turtle画动态的流星雨,快让你女朋友看看

---------------turtle源码集合--------------- Python教程91&#xff1a;关于海龟画图&#xff0c;Turtle模块需要学习的知识点 Python教程51&#xff1a;海龟画图turtle画&#xff08;三角形、正方形、五边形、六边形、圆、同心圆、边切圆&#xff0c;五角星&#xff0c;椭…

论文阅读:GamutMLP A Lightweight MLP for Color Loss Recovery

这篇文章是关于色彩恢复的一项工作&#xff0c;发表在 CVPR2023&#xff0c;其中之一的作者是 Michael S. Brown&#xff0c;这个老师是加拿大 York 大学的&#xff0c;也是 ISP 领域的大牛&#xff0c;现在好像也在三星研究院担任兼职&#xff0c;这个老师做了很多这种类似的工…

【从零到Offer】MySQL最左匹配

前言 ​ 相信大家在日常开发时&#xff0c;也经常能听到“最左匹配”这个词&#xff0c;那么什么是最左匹配呢&#xff1f;本篇文章就带你一起探索“最左匹配”的神奇秘密。 什么是最左匹配 ​ 最左匹配&#xff0c;通常指的是最左前缀匹配原则&#xff0c;即MySQL在检索数据…

C++ 特殊类的实现

一、请设计一个类&#xff0c;不能被拷贝 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c;只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 在C98中&#xff1a;将拷贝构造函数与赋值运算符重载…

今天:旧时是这样“破五迎福”

昨&#xff08;正月初四&#xff09;天&#xff0c;笔者——“ 人民体验官 ”&#xff0c; 为了推广人民日报官方微博文化产品所发表在10余个网站自媒体平台上的文章《今天&#xff1a;大年初四迎灶神爷》&#xff0c;不知何故被笔者寄居养老城市的自媒体论坛反复拒之门外&…

Imgui(2) | macOS 绘制 CPU 占用率曲线

Imgui(2) | macOS 绘制 CPU 占用率曲线 文章目录 Imgui(2) | macOS 绘制 CPU 占用率曲线0. 简介1. 绘制曲线 - 以正弦函数为例1.1 基于 sf::RectangleShape 的渲染 - 不好看&#xff0c;效率低1.2 基于 sf::VertexArray 的绘制 2. 获取和绘制所有 CPU 的占用率2.1 测试程序 - 用…

LeetCode、136. 只出现一次的数字【简单,位运算】

文章目录 前言LeetCode、136. 只出现一次的数字【简单&#xff0c;位运算】题目链接与分类思路异或一遍运算 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术…

测试西门子博途S7-PLCSIM Advanced V5.0的使用

原创 honeytree 西门子博途S7-PLCSIM Advanced V5.0能支持S7-1500&#xff0c;S7-1500R/H&#xff0c;ET200SP&#xff0c;ET200pro的仿真&#xff0c;用此仿真器可以模拟实际的PLC&#xff0c;用于其他软件的连接&#xff0c;比如上位机软件、触摸屏软件,自己用高级语音开发…

BUGKU-WEB POST

题目描述 进入场景看下&#xff1a; 代码如下&#xff1a; $what$_POST[what]; echo $what; if($whatflag) echo flag{****};解题思路 形式和上一题&#xff08;get&#xff09;一样本题需要post一个what来查看flag 相关工具 使用插件hackbar 来传post参数 解题步骤 使用…

项目计划制定攻略:从构思到执行的完整指南

在任何项目中&#xff0c;制定一个全面、详细的项目计划是至关重要的。项目计划是项目成功的基石&#xff0c;它提供了项目的路线图和指导&#xff0c;帮助团队成员了解项目的目标、里程碑和时间表。本文将详细介绍如何制定一个高质量的项目计划&#xff0c;确保项目顺利实施。…