【数据结构】二叉树篇|『构造二叉树』刷题

在这里插入图片描述

  • 博主简介:努力学习的22级计算机科学与技术本科生一枚🌸
  • 博主主页: @是瑶瑶子啦
  • 每日一言🌼: 所谓自由,不是随心所欲,而是自我主宰。——康德

目录

  • 一、前言
  • 二、刷题
    • 1、最大二叉树
    • 2、从前序与中序遍历序列构造二叉树
    • 3、从中序与后序遍历序列构造二叉树
    • 4、 根据前序和后序遍历构造二叉树

一、前言

🍊 二叉树的构造问题一般都是使用「分解问题」的思路:构造整棵树 = 根节点 + 构造左子树 + 构造右子树
( 关键在于明确递归函数的定义,然后利用这个定义,构建二叉树的套路很简单,先找到根节点,然后找到并递归构造左右子树即可)

二、刷题

1、最大二叉树

🔗654. 最大二叉树
在这里插入图片描述

 public TreeNode constructMaximumBinaryTree(int[] nums) {if(nums==null||nums.length==0){return null;}//1、找到最大元素,构造根节点int max = nums[0];int index = 0;for (int i = 1; i < nums.length; i++){if(nums[i] > max){index = i;max = nums[i];}}TreeNode root = new TreeNode(max);//左子树和右子树数组构造int[] numsLeft = Arrays.copyOfRange(nums, 0, index);int[] numsRight = Arrays.copyOfRange(nums,index+1, nums.length);root.left = constructMaximumBinaryTree(numsLeft);root.right = constructMaximumBinaryTree(numsRight);return root;}

2、从前序与中序遍历序列构造二叉树

🔗105. 从前序与中序遍历序列构造二叉树

  • 👧🏻思路:

    • 大的框架还是分解成子问题,这里定义一个递归函数:build(递归函数的定义:给定二叉树前序遍历、中序遍历数组、前序数组起始坐标、前序数组末尾坐标、中序数组起始坐标、中序数组末尾坐标)
    • 在递归函数前序位置需要确定左子树两个数组的的四个坐标和右子树的四个坐标,核心是算出当前root在中序数组中的位置rootIndex
      在这里插入图片描述
  • 🙇🏻‍♀️代码:

    	public TreeNode buildTree(int[] preorder, int[] inorder) {//递归函数的定义:给定二叉树前序遍历、中序遍历数组、前序数组起始坐标、前序数组末尾坐标、中序数组起始坐标、中序数组末尾坐标int pStart = 0;int pEnd = preorder.length-1;int iStart = 0;int iEnd = inorder.length-1;return build(preorder,inorder, pStart, pEnd, iStart, iEnd);}public TreeNode build(int[] preorder, int[] inorder, int pStart, int pEnd, int iStart, int iEnd){if(pStart > pEnd){return null;}//1、先在前序数组中找到根节点TreeNode root = new TreeNode(preorder[pStart]);//2、在中序数组中找到根节点,划分左右数组int rootIndex = -1;int leftSize = 0;for(int  i = iStart; i <= iEnd; i++){if(inorder[i] == root.val){rootIndex = i;leftSize = i-iStart;break;}}root.left = build(preorder, inorder, pStart+1, pStart+leftSize, iStart ,rootIndex-1);root.right = build(preorder, inorder, pStart+leftSize+1, pEnd, rootIndex+1, iEnd);return root;}
    

3、从中序与后序遍历序列构造二叉树

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

  • 👧🏻思路:

    • 同上,关键在于四个坐标的确定要准确
      在这里插入图片描述
  • 🙇🏻‍♀️代码:

     public TreeNode buildTree(int[] inorder, int[] postorder) {int inStart = 0;int inEnd = inorder.length -1;int posStart = 0;int posEnd = postorder.length - 1;return build(inorder, postorder, inStart, inEnd, posStart, posEnd);}public TreeNode build(int[] inorder, int[] postorder, int inStart, int inEnd, int posStart, int posEnd){if(posStart>posEnd){return null;}TreeNode root = new TreeNode(postorder[posEnd]);//得到根节点//找到根节点在中序数组中的位置int index = 0;int leftSize = 0;for(int i = inStart; i <= inEnd; i++ ){if(inorder[i] == root.val){index = i;leftSize = i - inStart;break;}}//*******构建左子树右子树 */root.left = build(inorder, postorder, inStart, index-1, posStart,posStart+leftSize -1);root.right = build(inorder, postorder, index+1, inEnd, posStart+leftSize,posEnd-1);return root;}
    

4、 根据前序和后序遍历构造二叉树

🔗889. 根据前序和后序遍历构造二叉树
在这里插入图片描述

  • 👧🏻思路:
    • 根据我们知道,只通过前序+后序是无法唯一构造一棵二叉树的。那么当然了,这题告诉我们有多个答案只用返回一个即可

    • 前两个(前序+中序&&中序+后序)可以唯一确定是因为通过前序/后序数组可以在前序位置唯一确定根节点root,然后在中序数组中可以根据root分成左中序数组和右中序数组,所以是可以确定唯一一颗二叉树的。

    • 而前序+后序按照这个思路其实也不是不行,因为前序和后序的数组划分是这样的:

      🤔咦,根据上图,貌似前序和中序可以构造唯一二叉树呀
      🙅🏻‍♀️不对,因为这里我们默认了一个大前提:root+1是left子树的跟,也就是默认了左子树至少有一个节点。但是实际上 ,左子树可能为空!——我们只是选取了其中一种可能情况而言。

    • 🙋🏻构建思路
      1. 首先将前序/后序遍历的第一个节点作为根节点root
      2. 前序数组中,root后面相邻元素作为左子树的根节点(坐标记为preStartL = preStart+1);
      3. 根据前序数组中的左子树根节点在后序数组中找到左子树的根节点:坐标记为posEndL
      4. 从而求得左子树节点个数leftSize = posStartL - posStart + 1,将左右子树划分
      5. 划分后即可确定左右子树的四个坐标点,带入递归函数分解成子问题即可

在这里插入图片描述

  • 🙇🏻‍♀️代码:

     public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {int preStart = 0;int preEnd = preorder.length -1;int posStart = 0;int posEnd = postorder.length - 1;return build(preorder, postorder, preStart, preEnd, posStart, posEnd);}public TreeNode build(int[] preorder, int[] postorder, int preStart, int preEnd, int posStart, int posEnd){if (preStart > preEnd) {return null;}//****** */!注意,这种情况必须特判!*****if (preStart == preEnd) {return new TreeNode(preorder[preStart]);}//************************************* */TreeNode root = new TreeNode(preorder[preStart]);//1、得到根节点//2、key:求leftSizeint preStartL = preStart+1;//int posEndL = -1;//2.1:找左子树根节点在后序数组中的位置for(int i = posStart; i <= posEnd; i++ ){if(postorder[i] == preorder[preStartL]){posEndL = i;break;}}int leftSize = posEndL - posStart + 1;root.left = build(preorder, postorder, preStartL, preStartL + leftSize -1, posStart, posEndL);root.right = build(preorder, postorder, preStartL + leftSize, preEnd, posEndL + 1, posEnd -1 );return root;}
    
  • 🍊注意!:在上面代码重点标出部分,需要特判的原因是:我们在思路部分已经讲过,这种方法默认左子树至少有一个节点(一棵树至少有两个节点),而preStart == preEnd并不满足这个大前提,所以需要特判!!


💐若有不懂的地方,欢迎随时在评论区or私信找瑶瑶子交流讨论🌺

在这里插入图片描述

  • Java岛冒险记【从小白到大佬之路】

  • LeetCode每日一题–进击大厂

  • Go语言核心编程

  • 算法

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

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

相关文章

R语言生存分析(机器学习)(2)——Enet(弹性网络)

弹性网络&#xff08;Elastic Net&#xff09;:是一种用于回归分析的统计方法&#xff0c;它是岭回归&#xff08;Ridge Regression&#xff09;和lasso回归&#xff08;Lasso Regression&#xff09;的结合&#xff0c;旨在克服它们各自的一些限制。弹性网络能够同时考虑L1正则…

Redis 持久化

一、RDB 1.1 RDB持久化流程 fork子进程是阻塞的&#xff0c;如果同时开启RDB和AOF&#xff0c;默认使用AOF。 1、Redis父进程首先判断: 当前是否在执行save&#xff0c;或bgsave/bgrewriteaof (aof文件重写命令)的子进程&#xff0c;如果在执行则bgsave命令直接返回。 2、父进…

MySQL中事务特性以及隔离机制

目录 一、什么是事务 二、事务特性——即ACID特性 三、事务的隔离级别 1、脏读 2、不可重复读 3、幻读 Read uncommitted&#xff1a; Read committed: Repeatable read: Serializable&#xff1a; 一、什么是事务 事务&#xff08;Transaction&#xff09;——一个最…

【华为Datacom 综合拓扑案例—分享篇】

拓扑图 题目要求 实验要求&#xff1a; 1、PC1\PC2\PC3\PC4采用DHCP自动获取IP地址&#xff0c;SW5作为服务器&#xff0c;SW3和SW4作为中继 创建地址池ip pool huawei1和ip pool huawei2&#xff0c;租期都为2天 2、SW3与SW4做链路聚合&#xff0c;采用LACP模式。SW3作为主…

蓝牙资讯|苹果Apple Watch可手势操控Mac和Apple TV等设备

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果公司近日获得了一项技术专利&#xff0c;概述了未来的 Apple Watch 手表&#xff0c;使用手势等操控 Mac 和 Apple TV 等设备。 该专利描述未来 Apple Watch 可以交互实现编辑图像、绘图、处理文…

期权定价模型系列【1】—BSM通用式模型

这是期权定价模型专栏的第一篇文章&#xff0c;此专栏旨在分享一些期权定价模型&#xff0c;将会从最基础的BSM模型开始写起&#xff0c;逐步扩散到蒙特卡洛模拟、二叉树等数值法模型&#xff0c;以及跳跃扩散模型、随机波动率模型&#xff0c;神经网络模型等等。 如果你觉得有…

堆叠注入进阶--(buuctf-随便注、GYCTF-black_list)【多方法详解】

了解一下 堆叠注入基础知识及其他题目&#xff1a; SQL-堆叠注入 终于有时间来填填坑了 Buuctf-随便注 算是堆叠注入中非常经典的题目了。 随便试试就能看到黑名单&#xff1a; 没了select&#xff0c;其实大概率就是堆叠注入 先探测一下&#xff1a; 1;show databases;…

C语言快速回顾(二)

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》&#xff0c;结合我自己的工作学习经历&#xff0c;我准备写一个音视频系列blog。C/C是音视频必…

使用chatGPT生成提示词,在文心一言生成装修概念图

介绍 家是情感的港湾&#xff0c;而家居装修则是将情感融入空间的艺术。如何在有限的空间里展现个性与美感&#xff0c;成为了现代人关注的焦点。而今&#xff0c;随着人工智能的发展&#xff0c;我们发现了一个新的创意助手——ChatGPT&#xff0c;它不仅为我们带来了更多可能…

【BEV Review】论文 Delving into the Devils of Bird’s-eye-view 2022-9 笔记

背景 一般来说&#xff0c;自动驾驶车辆的视觉传感器&#xff08;比如摄像头&#xff09;安装在车身上方或者车内后视镜上。无论哪个位置&#xff0c;摄像头所得到的都是真实世界在透视视图&#xff08;Perspective View&#xff09;下的投影&#xff08;世界坐标系到图像坐标系…

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测 目录 分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 Matlab实现基于…

运行python安装包没找到

一、错误信息 ImportError: dlopen(/Users/menghuiding/Library/Python/3.8/lib/python/site-packages/PIL/_imaging.cpython-38-darwin.so, 0x0002): tried: /Users/menghuiding/Library/Python/3.8/lib/python/site-packages/PIL/_imaging.cpython-38-darwin.so (mach-o fil…

最新智能AI系统+ChatGPT源码搭建部署详细教程+知识库+附程序源码

近期有网友问宝塔如何搭建部署AI创作ChatGPT&#xff0c;小编这里写一个详细图文教程吧。 使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到AIGC系统&#xff01; 增加手机端签到功能、优化后台总计绘画数量逻辑&#xff01;新增 MJ 官方图片重新生成指令功能同步官方 …

Linux服务器上配置HTTP和HTTPS代理

本文将向你分享如何在Linux服务器上配置HTTP和HTTPS代理的方法&#xff0c;解决可能遇到的问题&#xff0c;让你的爬虫项目顺利运行&#xff0c;畅爬互联网&#xff01; 配置HTTP代理的步骤 1. 了解HTTP代理的类型&#xff1a;常见的有正向代理和反向代理两种类型。根据实际需求…

聊聊RedisTemplate的各种序列化器

[版权申明] 非商业目的注明出处可自由转载 出自&#xff1a;shusheng007 文章目录 概述序列化器作用和原理JDK 序列化方式多一点 String 序列化方式JSON 序列化方式 总结源码 概述 在SpringBoot中使用redis基本上都是通过Spring Data Redis&#xff0c;那就不得不说RedisTempl…

手机照片误删怎么办,电脑照片误删怎么办怎么才能找回,EasyRecovery来帮您

手机照片误删怎么办&#xff0c;电脑照片误删怎么办怎么才能找回&#xff0c;EasyRecovery 2023来帮您&#xff01;&#xff01;&#xff01; EasyRecovery 2023是一款操作安全、价格便宜、用户自主操作的 数据恢复 方案&#xff0c;它支持从各种各样的 存储介质 恢复删除 或者…

Nginx安装及Minio集群反向动态代理配置(二)

安装所需插件 1、安装gcc gcc是linux下的编译器在此不多做解释&#xff0c;感兴趣的小伙伴可以去查一下相关资料&#xff0c;它可以编译 C,C,Ada,Object C和Java等语言 命令&#xff1a;查看gcc版本 [rootwww ~]# gcc -v -bash: gcc: 未找到命令 说明没有安装: 那就直接yu…

机器人CPP编程基础-02变量Variables

机器人CPP编程基础-01第一个程序Hello World 基础代码都可以借助人工智能工具进行学习。 C #include<iostream>using namespace std;main() {//Declaring an integer type variable A, allocates 4 bytes of memory.int A4;cout<<A <<endl;//Prints the a…

即将发布的 Kibana 版本可运行 Node.js 18

作者&#xff1a;Thomas Watson Kibana 构建在 Node.js 框架之上。 为了确保每个 Kibana 版本的稳定性和使用寿命&#xff0c;我们始终将捆绑的 Node.js 二进制文件保持为最新的最新长期支持 (LTS) 版本。 当 Node.js 版本 18 升级到 LTS 时&#xff0c;我们开始将 Kibana 升级…

最新AI系统ChatGPT网站程序源码+搭建教程/公众号/H5端/安装配置教程/完整知识库

1、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&#xff01;…