代码随想录第17天:二叉树

一、二叉搜索树的最近公共祖先(Leetcode 235)

由于是二叉搜索树,节点的值有严格的顺序关系:左子树的节点值都小于父节点,右子树的节点值都大于父节点。利用这一点,可以在树中更高效地找到最低公共祖先。

class Solution:def traversal(self, cur, p, q):# 递归的基本情况:当前节点为空,返回 Noneif cur is None:return cur# 如果当前节点的值大于 p 和 q 的值,说明 p 和 q 都在左子树中if cur.val > p.val and cur.val > q.val:  # 左left = self.traversal(cur.left, p, q)  # 在左子树中递归查找if left is not None:return left  # 如果左子树中找到了节点,返回该节点# 如果当前节点的值小于 p 和 q 的值,说明 p 和 q 都在右子树中if cur.val < p.val and cur.val < q.val:  # 右right = self.traversal(cur.right, p, q)  # 在右子树中递归查找if right is not None:return right  # 如果右子树中找到了节点,返回该节点# 如果左右子树都不为空,说明 p 和 q 分别在左右子树中return cur  # 返回当前节点,因为当前节点就是它们的最低公共祖先def lowestCommonAncestor(self, root, p, q):return self.traversal(root, p, q)  # 从根节点开始查找 p 和 q 的最低公共祖先

二、二叉搜索树中的插入操作(Leetcode 701)

如果要插入的值小于当前节点的值,应该插入到左子树;如果要插入的值大于当前节点的值,应该插入到右子树。

class Solution:# 插入值 val 到二叉搜索树中def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:# 如果当前节点为空,创建一个新的节点并返回if root is None or root.val == val:return TreeNode(val)  # 创建一个新的 TreeNode 节点,包含插入的值# 如果当前节点值大于 val,则应该将 val 插入到左子树elif root.val > val:# 如果左子树为空,直接插入该值作为左子节点if root.left is None:root.left = TreeNode(val)  # 创建一个新的节点,并赋值给左子节点else:# 如果左子树不为空,递归地在左子树中插入 valself.insertIntoBST(root.left, val)# 如果当前节点值小于 val,则应该将 val 插入到右子树elif root.val < val:# 如果右子树为空,直接插入该值作为右子节点if root.right is None:root.right = TreeNode(val)  # 创建一个新的节点,并赋值给右子节点else:# 如果右子树不为空,递归地在右子树中插入 valself.insertIntoBST(root.right, val)# 返回根节点,确保树的结构未被破坏return root

三、删除二叉搜索树中的节点(Leetcode 450)

删除节点的三种情况:

1、节点没有子节点(叶子节点):如果节点没有左子树也没有右子树(即叶子节点),直接删除该节点,返回 None,表示当前节点被删除。

2、节点只有右子树:如果节点没有左子树(root.left is None),那么可以用右子树代替当前节点。删除该节点并返回右子节点,实际上是把右子树提升为当前节点的子树。

3、节点只有左子树:如果节点没有右子树(root.right is None),那么可以用左子树代替当前节点。删除该节点并返回左子节点,实际上是把左子树提升为当前节点的子树。

4、节点有两个子树:从当前节点的右子树开始,递归找到右子树中最左的节点(cur.left is None),该节点就是右子树中的最小节点。将该最小节点的左子树指向当前节点的左子树。

返回右子树作为新树的根节点(也就是当前节点被删除,右子树的最小节点替代了它的位置)。

class Solution:# 删除二叉搜索树中的节点def deleteNode(self, root, key):# 如果当前节点为空,返回空# 表示没有找到节点或到达树的末端if root is None:return root# 如果当前节点的值等于要删除的值if root.val == key:# 如果节点没有子节点(叶子节点),直接删除该节点if root.left is None and root.right is None:return None# 如果节点只有右子树,直接返回右子树,删除当前节点elif root.left is None:return root.right# 如果节点只有左子树,直接返回左子树,删除当前节点elif root.right is None:return root.left# 如果节点有两个子树,找到右子树中的最小节点(左子树的最左节点)else:cur = root.right  # 从右子树开始# 寻找右子树中最小的节点(左子树最深的节点)while cur.left is not None:cur = cur.left# 将右子树最小节点的左子树指向当前节点的左子树cur.left = root.left# 返回右子树作为新的根节点,替代当前节点return root.right# 如果当前节点的值大于要删除的值,递归到左子树中删除if root.val > key:root.left = self.deleteNode(root.left, key)# 如果当前节点的值小于要删除的值,递归到右子树中删除if root.val < key:root.right = self.deleteNode(root.right, key)# 返回根节点,确保树的结构未被破坏return root

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

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

相关文章

C++中string库常用函数超详细解析与深度实践

目录 一、引言 二、基础准备&#xff1a;头文件与命名空间 三、string对象的创建与初始化(基础&#xff09; 3.1 直接初始化 3.2 动态初始化&#xff08;空字符串&#xff09; 3.3 基于字符数组初始化 3.4 重复字符初始化 四、核心函数详解 4.1 字符串长度相关 4.1.1 …

LanDiff:赋能视频创作,语言与扩散模型的融合力量

自从 Wan 2.1 发布以来&#xff0c;AI 视频生成领域似乎进入了一个发展瓶颈期&#xff0c;但这也让人隐隐感到&#xff1a;“DeepSeek 时刻”即将到来&#xff01;就在前几天&#xff0c;浙江大学与月之暗面联合推出了一款全新的文本到视频&#xff08;T2V&#xff09;生成模型…

【本地图床搭建】宝塔+Docker+MinIO+PicGo+cpolar:打造本地化“黑科技”图床方案

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言宝塔安装DockerMinIO 安装与设置cploar内网穿透PicGo下载与安装typora安装总结互动…

centos-LLM-生物信息-BioGPT-使用1

参考&#xff1a; GitHub - microsoft/BioGPT https://github.com/microsoft/BioGPT BioGPT&#xff1a;用于生物医学文本生成和挖掘的生成式预训练转换器 |生物信息学简报 |牛津学术 — BioGPT: generative pre-trained transformer for biomedical text generation and mini…

高效爬虫:一文掌握 Crawlee 的详细使用(web高效抓取和浏览器自动化库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Crawlee概述1.1 Crawlee介绍1.2 为什么 Crawlee 是网页抓取和爬取的首选?1.3 为什么使用 Crawlee 而不是 Scrapy1.4 Crawlee的安装二、Crawlee的基本使用2.1 BeautifulSoupCrawler的使用方式2.2 ParselCrawler的使…

架构总览怎么写,才算工业级?

📈系统架构文档是整个项目最重要的起点,但很多人第一章就“写穿了”: 不是写得太细,就是没有重点。想要写出高质量、能协作、能传承的架构文档,这一篇会告诉你应该怎么做—— ✅ 架构总览的终极目标 明确边界、定义角色、画清数据流 别讲执行细节,别深入函数调用。 ✅ 架…

优先级队列(堆二叉树)底层的实现:

我们继续来看我们的优先级队列&#xff1a; 优先级队列我们说过&#xff0c;他也是一个容器适配器&#xff0c;要依赖我们的容器来存储数据&#xff1b; 他的第二个参数就是我们的容器&#xff0c;这个容器的默认的缺省值是vector&#xff0c;然后他的第三个参数&#xff0c;我…

GIC驱动程序分析

今天呢&#xff0c;我们就来具体的讲一下GIC的驱动源码啦&#xff0c;这个才是重点来着&#xff0c;我们来看看&#xff1a; GIC中的重要函数和结构体&#xff1a; 沿着中断的处理流程&#xff0c;GIC涉及这4个重要部分&#xff1a; CPU从异常向量表中调用handle_arch_irq&am…

java操作redis库,开箱即用

application.yml spring:application:name: demo#Redis相关配置redis:data:# 地址host: localhost# 端口&#xff0c;默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最…

Cribl 通过Splunk search collector 来收集数据

今天利用Spliunk search collector 来收集数据啦:还是要先cribl 的官方文档: Splunk Search Collector | Cribl Docs Splunk Search Collector Cribl Stream supports collecting search results from Splunk queries. The queries can be both simple and complex, as well a…

What Was the “Game Genie“ Cheat Device, and How Did It Work?

什么是“Game Genie”作弊装置&#xff0c;它是如何工作的&#xff1f; First released in 1991, the Game Genie let players enter special codes that made video games easier or unlocked other functions. Nintendo didnt like it, but many gamers loved it. Heres wha…

位运算题目:连接连续二进制数字

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;连接连续二进制数字 出处&#xff1a;1680. 连接连续二进制数字 难度 5 级 题目描述 要求 给定一个整数 n \texttt{n} n&#xff0c;将 1 \text…

第十六届蓝桥杯Java b组(试题C:电池分组)

问题描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 样例输入&#xff1a; 2 3 1 2 3 4 1 2 3 4 样例输出: YES NO 说明/提示 评测用例规模与约定 对于 30% 的评测用例&#xff0c;1≤T≤10&#xff0c;2≤N≤100&#xff0c;1≤Ai​≤10^3。对于 100…

63. 评论日记

2025年4月14日18:53:30 雷军这次是真的累了_哔哩哔哩_bilibili

电商中的订单支付(内网穿透)

支付页面 接口文档 Operation(summary"获取订单信息") GetMapping("auth/{orderId}") public Reuslt<OrderInfo> getOrderInfo(Parameter(name"orderId",description"订单id",requiredtrue) PathVaariable Long orderId){OrderI…

MySQL表的使用(4)

首先回顾一下之前所学的增删查改&#xff0c;这些覆盖了平时使用的80% 我们上节课中学习到了MySQL的约束 其中Primary key 是主键约束&#xff0c;我们今天要学习的是外键约束 插入一个表 外键约束 父表 子表 这条记录中classid为5时候&#xff0c;不能插入&#xff1b; 删除…

Kotlin作用域函数

在 Kotlin 中&#xff0c;.apply 是一个 作用域函数&#xff08;Scope Function&#xff09;&#xff0c;它允许你在一个对象的上下文中执行代码块&#xff0c;并返回该对象本身。它的设计目的是为了 对象初始化 或 链式调用 时保持代码的简洁性和可读性。 // 不使用 apply va…

C#集合List<T>与HashSet<T>的区别

在C#中&#xff0c;List和HashSet都是用于存储元素的集合&#xff0c;但它们在内部实现、用途、性能特性以及使用场景上存在一些关键区别。 内部实现 List&#xff1a;基于数组实现的&#xff0c;可以包含重复的元素&#xff0c;并且元素是按照添加的顺序存储的。 HashSet&…

Python 实现的运筹优化系统数学建模详解(最大最小化模型)

一、引言 在数学建模的实际应用里&#xff0c;最大最小化模型是一种极为关键的优化模型。它的核心目标是找出一组决策变量&#xff0c;让多个目标函数值里的最大值尽可能小。该模型在诸多领域&#xff0c;如资源分配、选址规划等&#xff0c;都有广泛的应用。本文将深入剖析最大…

数据库的种类及常见类型

一&#xff0c;数据库的种类 最常见的数据库类型分为两种&#xff0c;关系型数据库和非关系型数据库。 二&#xff0c;关系型数据库介绍 生产环境主流的关系型数据库有 Oracle、SQL Server、MySQL/MariaDB等。 关系型数据库在存储数据时实际就是采用的一张二维表&#xff0…