每日一刷——二叉树的构建——12.12
第一题:最大二叉树
题目描述:654. 最大二叉树 - 力扣(LeetCode)
我的想法:
我感觉这个题目最开始大家都能想到的暴力做法就是遍历找到数组中的最大值,然后再遍历一遍,把在它左边的依次找到最大值,但是emmm,感觉效率很低,时间上肯定过不了
然后其实我会觉得这个题目跟大根堆和小根堆有一点像,,,就是先建立一个树来,然后如果大就上去,如果小就下来,但是有一点,怎么保证顺序??因为这样先建立一棵树来,再上移,好像不能保证??我浅浅画个图
那这样,是让6之后的全部向上移动吗,移动到6的右边?
题目分析:
嗯,看了一圈,好像没有人用小根堆,大根堆写哈,有用单调栈写的,有用DFS写,然后其实我那个初始想法版本也行,因为我的题解给我的就是这样写的,但是有一点不一样的是:它分割了数组+递归,我就是憨憨的非要把每一步写出来哈,,其实每一个节点做的事情一样,就一定一定抽象出来然后递归
就是相当于先找到数组中的最大值,然后左右两边分别交给左右儿子再去做分割
其实这样我们可以总结一个思想就是:
其实每一个节点,都是首先把自己构造出来,然后想办法构造自己的左右子树,就相当于每一个人都有当孩子和当父亲的一天,你要在孩子时期规定此时要做的事,要在父亲时期规定要做的事,然后每一个人的框架都是如此,只不过最后做出来的成果可能不一样
我的错误题解:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public TreeNode constructMaximumBinaryTree(int[] nums) {// 只要不断地传递就可以了,天哪噜return build(nums, 0, nums.length - 1);}TreeNode build(int[] nums ,int lo,int hi){if(lo>hi)return null;int max=nums[lo];int index=lo;//找到数组中地最大值,然后构建这个节点,再分配左右儿子的数组for(int i=lo+1;i<=hi;i++){if(nums[i]>max){max=nums[i];index=i;}}//一般,数组,====>传递下标,而不是非得要找到这个数是多少//创建这个节点TreeNode root =new TreeNode(max);root.left=build(nums,lo,index-1);root.left=build(nums,index+1,hi);return root;}
}
其实这个错误原因很好分析,一看,我去,右边的好像都没进去,所以直接检查代码,发现root.right写错了,写成了root.left
题解:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public TreeNode constructMaximumBinaryTree(int[] nums) {// 只要不断地传递就可以了,天哪噜return build(nums, 0, nums.length - 1);}TreeNode build(int[] nums ,int lo,int hi){if(lo>hi)return null;int max=nums[lo];int index=lo;//找到数组中地最大值,然后构建这个节点,再分配左右儿子的数组for(int i=lo+1;i<=hi;i++){if(nums[i]>max){max=nums[i];index=i;}}//一般,数组,====>传递下标,而不是非得要找到这个数是多少//创建这个节点TreeNode root =new TreeNode(max);root.left=build(nums,lo,index-1);root.right=build(nums,index+1,hi);return root;}
}
这个题目想清楚了之后,代码写起来和思维都不是很难的
第二题:从前序与中序遍历序列构造二叉树
题目描述:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
我的想法:
soga,这个!用前序和中序构建树,这个题目老师原来讲过,挺经典的题的
而且无论是前序还是后序,都必须要知道中序序列,才有唯一的二叉树确定
应该思路是这样的:
先从preorder里边开始,最开始是3 然后在inorder里边找3,3就把inorder分成了两半,左边是左子树里边的,右边就是右子树里边的,然后一直一直这样下去,最后这棵树就建好了(这里的思路有点小问题,看到后面就知道了)
我的题解:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {//1.建立头节点//拿到头节点在inorder中的位置,然后分割左右//左边就是新的inorder 右边也是新的inorder//2.建立左右子节点//3.什么时候结束?int index=0;return build(index,preorder,inorder,0,inorder.length-1);}public static TreeNode build(int index,int[] preorder, int[] inorder,int lf,int lr){if(lf<lr)return null;int findplace=0; TreeNode root =new TreeNode(preorder[index-1]);index++;for(int i=0;i<inorder.length;i++){if(inorder[i]==root.val){findplace=i;break;}}//突然感觉index传的不对啊??? 这个index是互通的吗??root.left=build(index,preorder,inorder,lf,findplace-1);root.right=build(index,preorder,inorder,findplace+1,lr);return root;}
}
为啥越界了???
题目分析:
for循环遍历确定index效率不高,可以考虑进一步优化:
因为题目说二叉树结点的值不重复,所以我们可以使用一个hashmap存储元素到索引的映射,这样就可以直接通过hashMap查到rootVal对应的index!!
我天!!!我知道了我的有一点的错误了!!
就是在preorder里边遍历,其实是不需要一个一个遍历,怎么说呢,因为你一直把index传给左右两颗子树,但是其实左右两颗子树里边需要的index并不相同,因为它们的元素就不相同,所以这样干,没有考虑周到,笑死我了,根据下面这张图应该能很明显的看到:preorder其实把它分成了这样两个部分
也就是说现在想指向某个值在数组里边对应的下标的时候,可以不需要遍历,直接用hashmap映射就可以了,它的值就是它的下标
题解:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public static HashMap<Integer,Integer> valToIndex =new HashMap<>();public TreeNode buildTree(int[] preorder, int[] inorder) {//1.建立头节点//拿到头节点在inorder中的位置,然后分割左右//左边就是新的inorder 右边也是新的inorder//2.建立左右子节点//3.什么时候结束?//HashMap优化for(int i=0;i<preorder.length;i++){valToIndex.put(inorder[i],i);}return build(0,preorder.length-1,preorder,inorder,0,inorder.length-1);}public static TreeNode build(int preFirst,int preLast,int[] preorder, int[] inorder,int lf,int lr){if(preFirst>preLast)return null;//分步完善 rootVal index leftSizeint rootVal =preorder[preFirst];int index=valToIndex.get(rootVal);int leftSize=index-lf;//构造父结点TreeNode root =new TreeNode(rootVal);/*有了hashmap这一步可以简化了for(int i=0;i<inorder.length;i++){if(inorder[i]==root.val){findplace=i;break;}} */root.left=build(preFirst+1 , preFirst+leftSize , preorder , inorder , lf , index-1);root.right=build(preFirst+leftSize+1 , preLast , preorder , inorder , index+1 , lr);return root;}
}
第三题:根据前序和后序遍历构造二叉树
题目描述:889. 根据前序和后序遍历构造二叉树 - 力扣(LeetCode)
我的想法:
我没有想法,惹惹惹,我在想这两个题有啥区别
我的题解:
题目分析:
前两道题:可以通过前序或者后序遍历找到根节点,然后根据中序遍历结果确定左右子树
但这一道题,可以确定根节点,但是无法确切的知道左右子树有哪些节点
比如:
但是解法还是和前两道题差别不大,通过控制左右子树的索引来构建
1.首先把前序遍历结果的第一个元素或者后序遍历结果的最后一个元素作为根节点的值
2.然后把前序遍历结果的第二个元素作为左子树的根节点的值
3.在后序遍历结果中寻找左子树跟节点的值,从而确定了左子树的索引边界,进而确定右子树的索引边界,然后递归构造左右子树即可
题解:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {//依然是下标到数的hash映射HashMap<Integer,Integer> valToIndex =new HashMap<>();public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {for(int i=0;i<postorder.length;i++){valToIndex.put(postorder[i],i);}return build(preorder,0,preorder.length-1,postorder,0,postorder.length-1);}TreeNode build(int[] preorder,int preStart ,int preEnd,int[] postorder,int postStart,int postEnd){if(preStart > preEnd)return null;if(preStart==preEnd)return new TreeNode(preorder[preStart]);//root节点对应的值就是前序遍历数组的第一个元素int rootVal =preorder[preStart];//root.left 的值是前序遍历元素第二个元素//通过前序和后序遍历构造二叉树的关键在于通过左子树的根节点//确定preorder 和postorder 中左右子树的元素区间int leftRootVal =preorder[preStart+1]; //leftRootVal 在后序遍历数组中的索引int index =valToIndex.get(leftRootVal);//左子树的元素个数int leftSize =index-postStart +1;//先构造出当前根节点TreeNode root =new TreeNode(rootVal);//递归构造左右子树//根据左子树的根节点索引和元素个数推导左右子树的索引边界root.left =build(preorder,preStart+1,preStart+leftSize,postorder,postStart,index);root.right =build(preorder,preStart+leftSize+1,preEnd,postorder,index+1,preEnd-1); //是因为左闭右开吗?? //好像因为要用到两个,preorder里边,一次性用两个,第一个为头节点,第二个为左孩子节点return root;}
}
我要背题目!!阿巴
相关文章:

每日一刷——二叉树的构建——12.12
第一题:最大二叉树 题目描述:654. 最大二叉树 - 力扣(LeetCode) 我的想法: 我感觉这个题目最开始大家都能想到的暴力做法就是遍历找到数组中的最大值,然后再遍历一遍,把在它左边的依次找到最大…...

Redis配置文件中 supervised指令
什么是Supervised? supervised模式允许Redis被外部进程管理器监控。通过这个选项,Redis能够在崩溃后自动重启,确保服务的高可用性。常见的进程管理器包括systemd和upstart。 开启方法 vim修改: sudo vi /etc/redis/redis.conf…...
OpenCV相机标定与3D重建(18)根据基础矩阵(Fundamental Matrix)校正两组匹配点函数correctMatches()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 优化对应点的坐标。 cv::correctMatches 是 OpenCV 库中的一个函数,用于根据基础矩阵(Fundamental Matrix)校…...

python脚本:向kafka数据库中插入测试数据
# coding:utf-8 import datetime import json import random import timefrom kafka import KafkaProducer生产者demo向branch-event主题中循环写入10条json数据注意事项:要写入json数据需加上value_serializer参数,如下代码producer KafkaProducer(val…...

10. 高效利用Excel导入报警信息
高效利用Excel导入报警信息 1.添加报警服务器2.导出报警EXCEL3.报警控件使用1.添加报警服务器 右键项目名称——Add New Sever——Tag Alarm and Event Sever 给报警服务器命名Alarm 给报警服务器分配优先级。如果想要使能历史的话需要和SQL sever配合使用,之前写过。记住这…...
k8s service 配置AWS nlb load_balancing.cross_zone.enabled
在Kubernetes中配置NLB(Network Load Balancer)的跨区域负载均衡(cross-zone load balancing),需要使用服务注解(service annotations)来实现。根据AWS官方文档,以下是配置NLB跨区域…...

国标GB28181网页直播平台EasyGBS国标GB28181-2016协议解读:媒体流保活机制
GB28181-2016在为视频监控系统提供统一的网络视频传输协议。这项标准主要用于公共安全视频监控系统,支持视频监控设备间的互联互通。其主要应用场景包括城市公共安全监控、交通监控、消防监控等。 GB28181-2016标准中的媒体流保活机制,主要是在确保视频…...
面试经验分享 | 杭州某安全大厂渗透测试岗
目录: 所面试的公司:某安全大厂 所在城市:杭州 面试职位:渗透测试工程师 面试过程: 面试官的问题: 1、面试官开始就问了我,为什么要学网络安全? …...

26. Three.js案例-自定义多面体
26. Three.js案例-自定义多面体 实现效果 知识点 WebGLRenderer WebGLRenderer 是 Three.js 中用于渲染场景的主要类。它支持 WebGL 渲染,并提供了多种配置选项。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选参数对象&…...

HarmonyOS-高级(四)
文章目录 应用开发安全应用DFX能力介绍HiLog使用指导HiAppEvent 🏡作者主页:点击! 🤖HarmonyOS专栏:点击! ⏰️创作时间:2024年12月11日11点18分 应用开发安全 应用隐私保护 隐私声明弹窗的作…...

Qt-chart 画折线图(以时间为x轴)
上图 代码 #include <iostream> #include <random> #include <qcategoryaxis.h>void MainWindow::testLine() {//1、创建图表视图QChartView* view new QChartView(this);//2.创建图表QChart* chart new QChart();//3.将图表设置给图表视图view->setCh…...
【入门】晶晶的补习班
描述 晶晶上初中了。妈妈认为晶晶应该更加用功学习,所以晶晶除了上学之外,还要参加妈妈为她报名的各科补习班。晶晶的妈妈给了晶晶的下周每天上补习班的小时数,晶晶同学想知道,下周平均一天要上多少小时的补习班(结果…...
c#动态更新替换json节点
需求项目json作为主模板,会应用到多个子模版,当后续项目变更只需要修改主模板中节点,并且能够动态更新到原来的子模版中去。 主模板示例: {"A": {"A1": "","A2": false,"A3"…...

cf补题日记
听退役选手建议,补40道C、D题。 (又又又开新专题。。。 进度:2/40 原题1: You are given a string ss, consisting of digits from 00 to 99. In one operation, you can pick any digit in this string, except for 00 or the…...
Golang学习笔记_01——包
文章目录 包(package)1. 定义2. 导入3. 初始化4. 可见性4. 注意4.1 包声明4.2 main包4.3 包的导入4.4标识符的可见性4.5 包的初始化4.6 避免命名冲突4.7 包的路径和名称4.8 匿名导入4.9 使用Go Modules 包(package) 在Golang&…...

RPC设计--应用层缓冲区,TcpBuffer
为什么需要应用层的buffer 为了方便数据处理,从fd上直接读写然后做包的组装、拆解不够方便方便异步发送,将数据写到应用层buffer后即可返回,让epoll即event_loop去异步发送。提高发送效率,多个小包可合并发送 buffer 设计 可以…...

基于单片机智能控制的饮水机控制系统
基于单片机智能控制的饮水机控制系统,以STC89C52单片机为核心,利用防水型DS18B20温度传感器对饮水机内的水温做出检测,其次利用水位传感器对饮水机内的水量做出检测,并显示在OLED液晶显示屏上。用户在使用饮水机时,通过…...

路径规划 | 改进的人工势场法APF算法进行路径规划(Matlab)
目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 改进的人工势场法(APF)路径规划算法 在路径规划中,人工势场法(APF)是一种常见的方法,但传统的APF算法容易陷入局部极小值,导致路径规…...
【云原生知识】Kubernets实践-前端服务如何访问后端服务
文章目录 概述步骤1:部署后端服务步骤2:配置Nginx步骤3:创建Nginx服务总结 如何确保 Nginx 能持续访问后端服务?相关文献 概述 假设你正在使用Kubernetes作为容器云平台,以下是如何配置Nginx以及相关服务,…...

【ubuntu18.04】ubuntu18.04安装EasyCwmp操作说明
参考链接 Tutorial – EasyCwmphttps://easycwmp.org/tutorial/ EasyCwmp 介绍 EasyCwmp 设计包括 2 个部分: EasyCwmp 核心:它包括 TR069 CWMP 引擎,负责与 ACS 服务器的通信。它是用 C 语言开发的。EasyCwmp DataModel:它包…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...