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

java算法day20

java算法day20

  • 701.二叉搜索树中的插入操作
  • 450.删除二叉搜索树中的节点
  • 108 将有序数组转换为二叉搜索树

本次的题目都是用递归函数的返回值来完成,多熟悉这样的用法,很方便。
其实我感觉,涉及构造二叉树的题目,用递归函数的返回值来做比较方便。每一层涉及对本层的构造,本层的操作结束后,是通过root.left = dfs(root.left,…)这样的方式来递归。
通过这种方式,到最后一层递归好之后,向上返回,这样树就构建起来了。

701.二叉搜索树中的插入操作

本题的特点是在递归出口。而又由这个递归出口,决定了递归的过程中应该干什么。

核心思路:
按BST的方式进行向下搜索,遇到空的位置就进行插入节点。


难点:
这个处理方式很重要。之前我想的是我干脆弄一个pre节点,这样方便我进行插入。但是这样逻辑就很难写。


所以就只能从递归构造左右子树的角度来做。
我说的构造就是这样
root.left = ?
root.right = ?
这样的方式。这样一旦遇到空,那么创建新节点,返回给上一层。这样root.left或者root.right就直接完成构造了。

所以就按这样的思路来。然后往下搜的时候肯定按BST的性质来往下递归。一旦当前节点大于root.val那么递归右子树。一旦往下层一走刚好碰到null,那么创建新节点,这个创建的新节点刚好就符合规则,挂到了这个正确的位置上。

所以说这样的递归方式已经决定好添加的这个节点的位置了,就等着到这个地方之后进行新节点的 创建。

class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {//递归出口//root为空,表示走到底了,按BST的性质,这个地方正式新节点的所在地,所以返回给上一层if(root==null){TreeNode newNode = new TreeNode(val);return newNode;}//按BST的性质进行往下搜索//但是这里的特点是,不断的构造,最后返回给上一层。是以构造的角度来看if(val>root.val){root.right = insertIntoBST(root.right,val);}else{root.left = insertIntoBST(root.left,val);}return root;}
}

难点就在这种以构造左右子树的角度的题做少了,可能想得到,但是写不出。


解法2:pre指针的思想

我一开始想用的这种做法,但是pre我处理的并不好。
所以从这个题解来学习处理pre节点。
注意这个题是迭代法,也就是用循环了。

class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {//注意这个并不是递归出口,这只是特判if (root == null) return new TreeNode(val);//pre初始化为root。//newRoot是用来后面构造好了返回结果的。TreeNode newRoot = root;TreeNode pre = root;//我个人感觉,怎样才能使得最后的时候,pre和cur一前一后?//技巧:pre的状态变更在一开是就更新为cur,而cur的变更则是在做完操作之后才变更。而且要针对cur做循环跳出的判断,否则到最后的时候,cur又跳进去了,pre会和cur同步。这样cur才会比pre多走一步。//内部的逻辑就是BST的向下搜索过程while (root != null) {pre = root;if (root.val > val) {root = root.left;} else if (root.val < val) {root = root.right;} }//这里就是判断这个新节点是挂在左边还是右边,因为cur只管遇到null就停下来if (pre.val > val) {pre.left = new TreeNode(val);} else {pre.right = new TreeNode(val);}return newRoot;}
}

450.删除二叉搜索树中的节点

这个就像手算删除二叉树节点的过程。删的时候判断属于哪种类型。
这里就把所有类型做一个判断,符合哪种就完成哪种删除,这就是本题的思路。
有以下五种情况:

第一种情况:没找到删除的节点,遍历到空节点直接返回了
找到删除的节点
第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

第五种比较抽象,但是这就是调整的方式,可以看看下图。
根据BST的性质,就是要把左子树挂到右子树最左下,才符合BST的性质。
请添加图片描述

class Solution {public TreeNode deleteNode(TreeNode root, int key) {//这个情况就属于没搜到,到了最底下就返回了,一直把null带给最顶层。if(root==null){return root;}//每到一个节点就先做判断,是不是要删的节点,不是再按BST往下层走if(root.val==key){//开始分情况讨论了,先拿下比较简单的情况if(root.left == null){//删除的节点,左子树为空,那么就把右子树挂上去,即把右子树返回给上层return root.right;}else if(root.right==null){return root.left;}else{TreeNode cur = root.right;while(cur.left!=null){cur = cur.left;}//此时已经到右子树的最左了,把root的左子树直接挂到cur的左子树上cur.left = root.left;//然后删除当前节点,root直接指向root.right就完成删除了root = root.right;//这里就完成了删除操作,然后返回结果。return root;}}//BST向下搜索构建的过程//这里一定要想清楚,因为是BST,所以往下就一个方向,所以往下递归构建就一个方向,//在每一层要么往左构建,要么往右构建。//key>root.val那往右进行递归到下一层,构建本层的root.rightif(key>root.val){root.right = deleteNode(root.right,key);}else if(key<root.val){root.left = deleteNode(root.left,key);}//这里已经是回来的逻辑了,所以构建的结果要返回给上一层。return root;}
}

108 将有序数组转换为二叉搜索树

题目一旦涉及到数组,那么根据经验,尽量不要重新定义左右区间数组,而是用下标来操作原数组。

本题有个要点,那就要满足平衡二叉搜索树。
因为对于有序数组而言,直接按顺序建一个线性树,那也满足二叉搜索树。
请添加图片描述
那要满足平衡二叉树那该怎么办?
本质是在找分割点。
递归的过程种,每次分割点取数组中间节点,然后递归构建左右子树就行了。
所以一层的子区间可以通过传递下标来完成表示。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return traversal(nums,0,nums.length-1);}TreeNode traversal(int[] nums,int left,int right){//递归出口,也就是递归构造的过程是区间不断收缩的过程,收缩完了就代表该位置没有节点构造。if(left>right){return null;}//每次取中间节点作为分割点int mid = left+(right-left)/2;//构造新节点TreeNode root = new TreeNode(nums[mid]);//递归构造左右子树,传递子区间。因为节点要取新的区间的中间节点。//这里显然是左闭右闭写法。root.left = traversal(nums,left,mid-1);root.right = traversal(nums,mid+1,right);//构造完了就返回,从底下返回来上,就全都构建好了。return root;}
}

相关文章:

java算法day20

java算法day20 701.二叉搜索树中的插入操作450.删除二叉搜索树中的节点108 将有序数组转换为二叉搜索树 本次的题目都是用递归函数的返回值来完成&#xff0c;多熟悉这样的用法&#xff0c;很方便。 其实我感觉&#xff0c;涉及构造二叉树的题目&#xff0c;用递归函数的返回值…...

web自动化测试-python+selenium+unitest

文章目录 Web自动化测试工具1. 主流的Web自动化测试工具2. Selenium家族史 Web自动化测试环境搭建基于Python环境搭建示例&#xff1a;通过程序启动浏览器&#xff0c;并打开百度首页&#xff0c;暂停3秒&#xff0c;关闭浏览器 页面元素定位1. 如何进行元素定位&#xff1f;2.…...

LeetCode题练习与总结:组合两个表--175

一、题目描述 SQL Schema > Pandas Schema > 表: Person ---------------------- | 列名 | 类型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- personId 是该表的主…...

数据结构:二叉搜索树(简单C++代码实现)

目录 前言 1. 二叉搜索树的概念 2. 二叉搜索树的实现 2.1 二叉树的结构 2.2 二叉树查找 2.3 二叉树的插入和中序遍历 2.4 二叉树的删除 3. 二叉搜索树的应用 3.1 KV模型实现 3.2 应用 4. 二叉搜索树分析 总结 前言 本文将深入探讨二叉搜索树这一重要的数据结构。二…...

深入理解Prompt工程

前言&#xff1a;因为大模型的流行&#xff0c;衍生出了一个小领域“Prompt工程”&#xff0c;不知道大家会不会跟小编一样&#xff0c;不就是写提示吗&#xff0c;这有什么难的&#xff0c;不过大家还是不要小瞧了Prompt工程&#xff0c;现在很多大模型把会“Prompt工程”作为…...

代码随想录算法训练营day6 | 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1.两数之和

文章目录 哈希表键值 哈希函数哈希冲突拉链法线性探测法 常见的三种哈希结构集合映射C实现std::unordered_setstd::map 小结242.有效的字母异位词思路复习 349. 两个数组的交集使用数组实现哈希表的情况思路使用set实现哈希表的情况 202. 快乐数思路 1.两数之和思路 总结 今天是…...

vue3 vxe-table 点击行,不显示选中状态,加上设置isCurrent: true就可以设置选中行的状态。

1、上个图&#xff0c;要实现这样的&#xff1a; Vxe Table v4.6 官方文档 2、使用 row-config.isCurrent 显示高亮行&#xff0c;当前行是唯一的&#xff1b;用户操作点击选项时会触发事件 current-change <template><div><p><vxe-button click"sel…...

Linux没有telnet 如何测试对端的端口状态

前段时间有人问uos没有telnet&#xff0c;又找不到包。 追问了一下为什么非要安装telnet&#xff0c;答复是要测试对端的端口号。 这里简单介绍一下&#xff0c;测试端口号的方法有很多&#xff0c;telent只是在windows上经常使用&#xff0c;linux已很少安装并使用该命令&…...

花几千上万学习Java,真没必要!(二十九)

1、基本数据类型包装类&#xff1a; 测试代码1&#xff1a; package apitest.com; //使用Integer类的不同方法处理整数。 //将字符串转换为整数&#xff08;parseInt&#xff09;和Integer对象&#xff08;valueOf&#xff09;&#xff0c; //将整数转换回字符串&#xff08;…...

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意&#xff1a;XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下&#xff0c;之后又将XML文件复制到相同的目录下&#xff0c;需要删除引用&am…...

WordPress原创插件:自定义文章标题颜色

插件设置截图 文章编辑时&#xff0c;右边会出现一个标题颜色设置&#xff0c;可以设置为任何颜色 更新记录&#xff1a;从输入颜色css代码&#xff0c;改为颜色选择器&#xff0c;更方便&#xff01; 插件免费下载 https://download.csdn.net/download/huayula/89585192…...

Unity分享:继承自MonoBehaviour的脚步不要对引用类型的字段在声明时就初始化

如果某些字段在每个构造函数中都要进行初始化&#xff0c;很多人都喜欢在字段声明时就进行初始化&#xff0c;对于一个非继承自MonoBehaviour的脚步&#xff0c;这样做是没有问题的&#xff0c;然而继承自MonoBehaviour后就会造成内存的浪费&#xff0c;为什么呢&#xff1f;因…...

.NET Core中如何集成RabbitMQ

在.NET Core中集成RabbitMQ主要涉及到几个步骤&#xff0c;包括安装RabbitMQ的NuGet包、建立连接、定义队列、发送和接收消息等。下面是一个简单的指南来展示如何在.NET Core应用程序中集成RabbitMQ。 目录 1. 安装RabbitMQ.Client NuGet包 2. 建立连接 3. 定义队列 4. 发…...

嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议数据可视化:智能物流管理系统设计思路流程(附代码示例)

目录 项目概述 系统设计 硬件设计 软件设计 系统架构图 代码实现 1. STM32微控制器与传感器代码 代码讲解 2. MQTT Broker设置 3. 数据接收与处理 代码讲解 4. 数据存储与分析 5. 数据分析与可视化 代码讲解 6. 数据可视化 项目总结 项目概述 随着电子商务的快…...

.net core docker部署教程和细节问题

在.NET Core中实现Docker一键部署&#xff0c;通常涉及以下几个步骤&#xff1a;编写Dockerfile以定义镜像构建过程、构建Docker镜像、运行Docker容器&#xff0c;以及&#xff08;可选地&#xff09;使用自动化工具如Docker Compose或CI/CD工具进行一键部署。以下是一个详细的…...

php数据库链接

Php超全局变量 GET 和 POST 都创建一个数组&#xff08;例如 array&#xff08; key1 > value1&#xff0c; key2 > value2&#xff0c; key3 > value3&#xff0c; ...&#xff09;&#xff09;。此数组包含键/值对&#xff0c;其中 键是表单控件的名称&#xff0c;…...

python+vue3+onlyoffice在线文档系统实战20240726笔记,左侧菜单实现和最近文档基本实现

解决右侧高度过高的问题 解决方案&#xff1a;去掉右侧顶部和底部。 实现左侧菜单 最近文档&#xff0c;纯粹文档 我的文档&#xff0c;既包括文件夹也包括文件 共享文档&#xff0c;别人分享给我的 基本实现代码&#xff1a; 渲染效果&#xff1a; 简单优化 设置默认菜…...

vue中的nexttrick

Vue.js 是一个用于构建用户界面的渐进式框架&#xff0c;它允许开发者通过声明式的数据绑定来构建网页应用。在 Vue 中&#xff0c;nextTick 是一个非常重要的 API&#xff0c;它用于延迟回调的执行&#xff0c;直到下次 DOM 更新循环之后。 为什么使用 nextTick&#xff1f; …...

【BUG】已解决:ModuleNotFoundError: No module named ‘requests‘

ModuleNotFoundError: No module named ‘requests‘ 目录 ModuleNotFoundError: No module named ‘requests‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&a…...

深入理解JS中的发布订阅模式和观察者模式

发布/订阅模式(Publish/Subscribe)和观察者模式(Observer Pattern)在概念上非常相似,都是用于实现对象之间的松耦合通信。尽管它们在实现细节和使用场景上有所不同,但核心思想是相通的。 观察者模式 直接通信:在观察者模式中,观察者(Observer)直接订阅主题(Subject…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...