当前位置: 首页 > news >正文

每日一刷——二叉树的构建——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

第一题&#xff1a;最大二叉树 题目描述&#xff1a;654. 最大二叉树 - 力扣&#xff08;LeetCode&#xff09; 我的想法&#xff1a; 我感觉这个题目最开始大家都能想到的暴力做法就是遍历找到数组中的最大值&#xff0c;然后再遍历一遍&#xff0c;把在它左边的依次找到最大…...

Redis配置文件中 supervised指令

什么是Supervised&#xff1f; supervised模式允许Redis被外部进程管理器监控。通过这个选项&#xff0c;Redis能够在崩溃后自动重启&#xff0c;确保服务的高可用性。常见的进程管理器包括systemd和upstart。 开启方法 vim修改&#xff1a; sudo vi /etc/redis/redis.conf…...

OpenCV相机标定与3D重建(18)根据基础矩阵(Fundamental Matrix)校正两组匹配点函数correctMatches()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 优化对应点的坐标。 cv::correctMatches 是 OpenCV 库中的一个函数&#xff0c;用于根据基础矩阵&#xff08;Fundamental Matrix&#xff09;校…...

python脚本:向kafka数据库中插入测试数据

# coding:utf-8 import datetime import json import random import timefrom kafka import KafkaProducer生产者demo向branch-event主题中循环写入10条json数据注意事项&#xff1a;要写入json数据需加上value_serializer参数&#xff0c;如下代码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&#xff08;Network Load Balancer&#xff09;的跨区域负载均衡&#xff08;cross-zone load balancing&#xff09;&#xff0c;需要使用服务注解&#xff08;service annotations&#xff09;来实现。根据AWS官方文档&#xff0c;以下是配置NLB跨区域…...

国标GB28181网页直播平台EasyGBS国标GB28181-2016协议解读:媒体流保活机制

GB28181-2016在为视频监控系统提供统一的网络视频传输协议。这项标准主要用于公共安全视频监控系统&#xff0c;支持视频监控设备间的互联互通。其主要应用场景包括城市公共安全监控、交通监控、消防监控等。 GB28181-2016标准中的媒体流保活机制&#xff0c;主要是在确保视频…...

面试经验分享 | 杭州某安全大厂渗透测试岗

目录&#xff1a; 所面试的公司&#xff1a;某安全大厂   所在城市&#xff1a;杭州    面试职位&#xff1a;渗透测试工程师    面试过程&#xff1a;  面试官的问题&#xff1a;    1、面试官开始就问了我&#xff0c;为什么要学网络安全&#xff1f;   …...

26. Three.js案例-自定义多面体

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

HarmonyOS-高级(四)

文章目录 应用开发安全应用DFX能力介绍HiLog使用指导HiAppEvent &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;HarmonyOS专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;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…...

【入门】晶晶的补习班

描述 晶晶上初中了。妈妈认为晶晶应该更加用功学习&#xff0c;所以晶晶除了上学之外&#xff0c;还要参加妈妈为她报名的各科补习班。晶晶的妈妈给了晶晶的下周每天上补习班的小时数&#xff0c;晶晶同学想知道&#xff0c;下周平均一天要上多少小时的补习班&#xff08;结果…...

c#动态更新替换json节点

需求项目json作为主模板&#xff0c;会应用到多个子模版&#xff0c;当后续项目变更只需要修改主模板中节点&#xff0c;并且能够动态更新到原来的子模版中去。 主模板示例&#xff1a; {"A": {"A1": "","A2": false,"A3"…...

cf补题日记

听退役选手建议&#xff0c;补40道C、D题。 &#xff08;又又又开新专题。。。 进度&#xff1a;2/40 原题1&#xff1a; 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——包

文章目录 包&#xff08;package&#xff09;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 包&#xff08;package&#xff09; 在Golang&…...

RPC设计--应用层缓冲区,TcpBuffer

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

基于单片机智能控制的饮水机控制系统

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

路径规划 | 改进的人工势场法APF算法进行路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 改进的人工势场法&#xff08;APF&#xff09;路径规划算法 在路径规划中&#xff0c;人工势场法&#xff08;APF&#xff09;是一种常见的方法&#xff0c;但传统的APF算法容易陷入局部极小值&#xff0c;导致路径规…...

【云原生知识】Kubernets实践-前端服务如何访问后端服务

文章目录 概述步骤1&#xff1a;部署后端服务步骤2&#xff1a;配置Nginx步骤3&#xff1a;创建Nginx服务总结 如何确保 Nginx 能持续访问后端服务&#xff1f;相关文献 概述 假设你正在使用Kubernetes作为容器云平台&#xff0c;以下是如何配置Nginx以及相关服务&#xff0c;…...

【ubuntu18.04】ubuntu18.04安装EasyCwmp操作说明

参考链接 Tutorial – EasyCwmphttps://easycwmp.org/tutorial/ EasyCwmp 介绍 EasyCwmp 设计包括 2 个部分&#xff1a; EasyCwmp 核心&#xff1a;它包括 TR069 CWMP 引擎&#xff0c;负责与 ACS 服务器的通信。它是用 C 语言开发的。EasyCwmp DataModel&#xff1a;它包…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...