代码随想录算法训练营第二十四天|235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

##递归法
 class Solution:
     def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
         if not root:
             return  TreeNode(val)
         #向左遍历
         if val > root.val:    
             root.right = self.insertIntoBST(root.right,val) #1
         #向右遍历
         elif val < root.val:
            root.left =  self.insertIntoBST(root.left,val) #2
         return root

235. 二叉搜索树的最近公共祖先

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

提到二叉搜索树,那么我们就要好好利用它的特性 

p和q的公共祖先一定是在p和q的中间的(如果一个节点在p和q之间,那么说明p在这个节点的左子树,q在这个节点的右子树中),所以:

p和q的最近公共祖先一定是小于等于p和q的中的最大值,大于等于p和q中的最小值的

所以当前遍历的节点如果在这个范围的右边,那么我们就向左遍历,反之向右遍历

是否一定是最近的公共祖先呢?假设现在找到了一个公共节点,如果我们再向左或者右遍历,那么就会错过p或者q。所以找到的一定是最近的公共祖先

递归法

递归的三要素:

第一要素:明确这个函数想要干什么

传入一个节点,找到这个节点对应的二叉树中p和q的最近公共祖先

第二要素:寻找递归结束条件

如果传入的是空那么就return 空

如果传入的节点的值就在p和q之间,那么就return 这个节点

第三要素:找出函数的等价关系式

如果当前遍历的节点如果在这个范围的右边,那么我们就继续向左遍历,反之向右遍历

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        ##终止条件
        if not root:
            return None
        if root.val>min(p.val,q.val) and root.val < max(p.val,q.val):
            return root
        ##递归遍历
        if root.val < min(p.val,q.val):
            return self.lowestCommonAncestor(root.right,p,q)
        elif root.val > max(p.val,q.val):
            return self.lowestCommonAncestor(root.left,p,q)
        else:
            return root

迭代法 

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        ##终止条件
        if not root:
            return None
        while root:
            if root.val < min(p.val,q.val):
                root = root.right
            elif root.val > max(p.val,q.val):
                root = root.left
            else:
                return root

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

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

有多种插入方式,我们选择直接在叶子节点插入

要点:在二叉搜索树中,插入任何一个节点,都可以在叶子节点找到它的位置。主要是要比较要插入的节点与当前遍历到的节点的大小,决定我们是向左还是向右遍历,直到遇到空节点,将数值插入即可,保证二叉搜索树的特性不变。

递归法

迭代法

##迭代法
class Solution:
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if not root:
            return TreeNode(val)
        current = root
        while  current: ##不可以用root循环,因为会不变改变root,最后还要返回root
            #向左遍历
            if val > current.val:
                if current.right == None:
                    current.right =  TreeNode(val)
                    break
                current= current.right
            #向右遍历
            elif val < current.val:
                if current.left == None:
                    current.left =  TreeNode(val)
                    break
                current= current.left
        return root

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

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

 与上题相比添加节点只要在叶子节点添加即可,但是删除二叉树的节点需要改变二叉树的结构,比上题难得多。分五种情况

①没有找到删除的节点

②要删除的节点是叶子节点:不用改变二叉树的结构,较简单

③要删除的节点左不为空,右为空

④要删除的节点左为空,右不为空

⑤左右都不空。假设我们让右子树即位,那么原来左子树就要寻找一个新的父节点,只需要找比原来父节点稍微大一点的数即可。即右子树中最左侧的节点,这样就比左子树稍微大一点点。

递归的三要素:

第一要素:明确这个函数想要干什么

传入一个节点,删除以这个节点为根节点的二叉树中的特定值,并返回删除后的二叉树(根节点)

第二要素:寻找递归结束条件

上面说到的5点

第三要素:找出函数的等价关系式

根据特定的搜索方向删除左子树或者右子树中的值,删除完之后不要忘记,让根节点指向它们,因为根节点还在的,我们只是修改了根节点的左子树或者右子树,删完之后要更新一下

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        #如果是空
        if not root:
            return None
        #如果当前节点是要删除的节点
        if root.val == key:
            #如果要删除的节点是叶子节点
            if not root.left and not root.right:
                return None
            #左不为空,右为空
            if root.left and not root.right:
                return root.left
            #左为空,右不为空
            if not root.left and root.right:
                return root.right
            if root.left and root.right:
                cur = root.right
                ##找到右子树最左边的节点
                while cur.left:
                    cur = cur.left
                cur.left = root.left
                ##相当于左孩子为空了,直接返回右孩子即可
                return root.right
        #递归,二叉搜索树决定了搜索的方向
        else:
            if key > root.val:
               node =  self.deleteNode(root.right,key)
               root.right = node
               return root
            else: 
                node =  self.deleteNode(root.left,key)
                root.left = node
                return root

这几道题目的递归函数都是有返回值的,并且让上一个节点的左孩子或者右孩子接住了,之后还是要好好消化消化

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子版图书制作,一键转换可仿真翻页的画册

在数字化浪潮的冲击下&#xff0c;传统纸质图书逐渐被电子版图书取而代之。电子版图书以其便携、环保、更新快速等特点&#xff0c;吸引了越来越多的读者。制作一款既具备电子图书的便捷性&#xff0c;又能仿真翻页的画册&#xff0c;成为当下图书出版行业的新趋势 1.要制作电子…

企业数据保护,从严防内部信息泄露开始

在当今的数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;随之而来的是数据安全威胁&#xff0c;尤其是内部信息泄露&#xff0c;这不仅会导致企业面临巨大的经济损失&#xff0c;还可能损害企业的品牌形象和客户信任。因此&#xff0c;从严防内部信息…

56 关于 linux 的 oom killer 机制

前言 这里主要讲的是 linux 的 oom killer 机制 在系统可用内存较少的情况下&#xff0c;内核为保证系统还能够继续运行下去&#xff0c;会选择杀掉一些进程释放掉一些内存。 通常oom_killer的触发流程是&#xff1a;进程A想要分配物理内存&#xff08;通常是读写内存&#…

新能源汽车中HEV与PHEV分别代表什么车型,它们与传统燃油车都有什么区别?

前言 新能源汽车正逐渐成为全球汽车工业的主流方向&#xff0c;而HEV&#xff08;Hybrid Electric Vehicle&#xff09;和PHEV&#xff08;Plug-in Hybrid Electric Vehicle&#xff09;这两种混合动力车型在这一转型过程中扮演着重要角色。下面我们详细探讨HEV与PHEV的定义&a…

基于FPGA的视频矩阵 视频拼接 无缝切换解决方案

视频矩阵 视频矩阵 视频拼接 无缝切换 1. 最大支持144路HDMI视频输入&#xff0c;最大支持144路路HDMI输出&#xff0c;完全交叉切换。 2. 与包括1080p/60的所有HDTV分辨率和高达1920*1200的PC的分辨率兼容&#xff1b; 3. 支持HDMI 1.3a、HDCP 1.3、HDCP 1.4、以及DVI 1.0协…

如何使用visual vm和jstat进行远程监控

如何使用visual vm和jstat进行监控 安装visual vm 好像从jdk某个版本开始&#xff0c;jdk的bin目录下就不自带jvisualvm了&#xff0c;需要从官网下载一个visual vm。 打开visual vm Local是你本地的&#xff0c;无需多言。 先准备下必备的插件 如何通过visual vm观测远程…

Prometheus监控Kubernetes Pod状态

本文将介绍如何配置Prometheus的告警规则&#xff0c;实现对于Kubernetes Pod状态的监控。 1.Pod的状态类型 在Prometheus 监控Kubernetes Pod 状态时&#xff0c;通常可以观察到以下几种状态情况&#xff1a; 1. Running&#xff08;运行中&#xff09; Pod 处于运行状态意…

Spring Framework-IoC详解

IoC的概念和作用 在介绍Ioc之前&#xff0c;我们首先先了解一下以下内容 什么是程序的耦合 耦合性(Coupling)&#xff0c;也叫耦合度&#xff0c;是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度…

Java毕业设计 基于SpringBoot vue新能源充电系统

Java毕业设计 基于SpringBoot vue新能源充电系统 SpringBoot 新能源充电系统 功能介绍 首页 图片轮播 充电桩 充电桩类型 充电桩详情 充电桩预约 新能源公告 公告详情 登录注册 个人中心 余额充值 修改密码 充电桩报修 充电桩预约订单 客服 后台管理 登录 个人中心 修改密码…

【Linux】模拟实现bash(简易版)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

redis深入理解之数据存储

1、redis为什么快 1&#xff09;Redis是单线程执行&#xff0c;在执行时顺序执行 redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取(socket 读)、解析、执行、内容返回 (socket 写)等都由一个顺序串行的主线…

权力集中,效率提升,中心化模式的优势与挑战

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自热榜文章&#x1f525;&#xff1a;探索设计模式的魅力&#xff1a;权力集中…

Microsoft Project使用简明教程

一.认识Microsoft Project Microsoft Project 是微软公司开发的项目管理软件&#xff0c;用于规划、协调和跟踪项目的进度、资源和预算&#xff0c;如下图所示&#xff0c;左边是任务的显示&#xff0c;右边是一个日程的显示图&#xff0c;最上方的长方形处在我们项目设定日程…

【oracle数据库安装篇三】Linux6.8单机环境oracle11g容灾ADG搭建

说明 DataGuard 是在主节点与备用节点间通过日志同步来保证数据的同步&#xff0c;可以实现数据库快速切换与灾难性恢复。用户能够在对主数据库影响很小的情况下&#xff0c;实现主备数据库的同步。 关联文章 【oracle数据库安装篇一】Linux5.6基于LVM安装oracle11gR2单机 【…

Pandas数据取值与选择

文章目录 第1关&#xff1a;Series数据选择第2关&#xff1a;DataFrame数据选择方法 第1关&#xff1a;Series数据选择 编程要求 本关的编程任务是补全右侧上部代码编辑区内的相应代码&#xff0c;要求实现如下功能&#xff1a; 添加一行数据&#xff0c;时间戳2019-01-29值为…

vue开发网站—①调用$notify弹窗、②$notify弹窗层级问题、③js判断两个数组是否相同等。

一、vue中如何使用vant的 $notify&#xff08;展示通知&#xff09; 在Vue中使用Vant组件库的$notify方法来展示通知&#xff0c;首先确保正确安装了Vant并在项目中引入了Notify组件。 1.安装vant npm install vant --save# 或者使用yarn yarn add vant2.引入&#xff1a;在ma…

自存angular 自定义snackbar

定义 1.自定义样式 2.自定义组件 就在要使用snackbar的组件中 在module中引入该组件&#xff08;重新写一个组件也行的 直接引入就好&#xff09; 打开这个组件 给这个自定义的组件传参 这个自定义组件接参(类似对话框接参) 使用参数 在这个自定义组件中 做了点击如何关闭s…

企业信使运营管理平台功能介绍

企业信使运营管理平台是一种为企业提供内部协同、任务管理、沟通交流、文件共享等功能的综合性管理平台。该平台旨在提高企业内部的工作效率和沟通协作能力&#xff0c;提供便捷的工作管理工具&#xff0c;促进企业的业务发展。 内部协同功能 企业信使运营管理平台首先提供一种…

Navicat Data Modeler Ess for Mac:强大的数据库建模设计软件

Navicat Data Modeler Ess for Mac是一款专为Mac用户设计的数据库建模与设计工具&#xff0c;凭借其强大的功能和直观的界面&#xff0c;帮助用户轻松构建和管理复杂的数据库模型。 Navicat Data Modeler Ess for Mac v3.3.17中文直装版下载 这款软件支持多种数据库系统&#x…

android进阶-AIDL

参考&#xff1a;Android进阶——AIDL详解_android aidl-CSDN博客 AIDL&#xff08;Android 接口定义语言&#xff09;&#xff0c;可以使用它定义客户端与服务端进程间通信&#xff08;IPC&#xff09;的编程接口&#xff0c;在 Android 中&#xff0c;进程之间无法共享内存&…
最新文章