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

news2025/4/16 14:27:09

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

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

class Solution:
    def traversal(self, cur, p, q):
        # 递归的基本情况:当前节点为空,返回 None
        if 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:
                # 如果左子树不为空,递归地在左子树中插入 val
                self.insertIntoBST(root.left, val)
        
        # 如果当前节点值小于 val,则应该将 val 插入到右子树
        elif root.val < val:
            # 如果右子树为空,直接插入该值作为右子节点
            if root.right is None:
                root.right = TreeNode(val)  # 创建一个新的节点,并赋值给右子节点
            else:
                # 如果右子树不为空,递归地在右子树中插入 val
                self.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.coloradmin.cn/o/2335343.html

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

相关文章

面试篇 - GPT-1(Generative Pre-Training 1)

GPT-1&#xff08;Generative Pre-Training 1&#xff09; ⭐模型结构 Transformer only-decoder&#xff1a;GPT-1模型使用了一个12层的Transformer解码器。具体细节与标准的Transformer相同&#xff0c;但位置编码是可训练的。 注意力机制&#xff1a; 原始Transformer的解…

【从零实现高并发内存池】内存池整体框架设计 及 thread cache实现

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

3.6 函数图像描绘

1.函数描图步骤 2.渐进性 2.1 水平渐进线 2.2 垂直渐进线 2.3 斜渐近线 3.作图

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

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

ESP32开发之ubuntu环境搭建

1. 在Ubuntu官网下载Ubuntu server 20.04版本https://releases.ubuntu.com/20.04.6/ 2. 在vmware下安装Ubuntu 3. 改Ubuntu静态IP $ sudo vi /etc/netplan/00-installer-config.yaml# This is the network config written by ‘subiquity’ network: renderer: networkd eth…

2025年,HarmonyOS认证学习及考试

HarmonyOS应用开发者认证考试 基础认证 通过系统化的课程学习&#xff0c;熟练掌握 DevEco Studio&#xff0c;ArkTS&#xff0c;ArkUI&#xff0c;预览器&#xff0c;模拟器&#xff0c;SDK 等 HarmonyOS 应用开发的关键概念&#xff0c;具备基础的应用开发能力。 高级认证…

空间信息可视化——WebGIS前端实例(一)

技术栈&#xff1a;原生HTML 源代码&#xff1a;CUGLin/WebGIS: This is a project of Spatial information visualization 4 全国贫困县可视化系统 4.1 系统设计思想 党的十九大报告明确指出,要“确保到2020年我国现行标准下农村贫困人口实现脱贫,贫困县全部摘帽,解决区域…

10.第二阶段x64游戏实战-添加计时器

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;9.第二阶段x64游戏实战-创建项目代码获取人物属性 效果图&#xff1a; 当前游戏…

【论文阅读】MOE奠基论文《Adaptive Mixtures of Local Experts》

《Adaptive Mixtures of Local Experts》 前言一、让协同学习竞争1.1 方案1.2 方案演变的由来 二、让竞争学习协同2.1 竞争学习2.2 竞争学习协同 三、案例验证3.1 任务背景3.2 实验结果3.3 后续工作 (Future Work) 前言 论文提出了一个基于多个分离网络的有监督学习方案,该方案…

VM虚拟机安装及Ubuntu安装配置

VM虚拟机安装及Ubuntu安装配置 1、VM虚拟机安装2、创建虚拟机3、Ubuntu系统安装4、编译环境配置4.1 、Ubuntu和 Windows文件互传 文件互传4.1.1、 开启Ubunt下的FTP服务 4.2、 Ubuntu下NFS和SSH服务开启4.2.1、 NFS服务开启4.2.2、 SSH服务开启 4.3、 交叉编译器安装4.3.1 安装…

【C++ 进阶】泛型算法:概述

目录 一、泛型算法基础概念 1.1 什么是泛型算法&#xff1f; 1.2 核心设计原则 1.3 算法分类体系 1.4 与 STL 容器的关系 二、迭代器&#xff1a;泛型算法的 “钥匙” 2.1 迭代器类型 2.2 迭代器适配器 三、常用泛型算法分类与实战 3.1 非修改型算法&#xff08;只读…

系统与网络安全------Windows系统安全(10)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 域与活动目录 域相关概念 域和域控制器 域&#xff08;Domain&#xff09; 集中管理网络中多台计算机的一种逻辑模式 有别于工作组的对等式管理 是组织与存储资源的核心管理单元 域控制器&#xff08;D…

Linux vagrant 导入ubuntu到virtualbox

前言 vagrant 导入ubuntu虚拟机前提要求 安装 virtualbox 和vagrant<vagrant-disksize> (Linux 方式 Windows 方式)创建一键部署ubuntu虚拟机 /opt/vagrant 安装目录/opt/VirtualBox 安装目录/opt/ubuntu22/Vagrantfile (可配置网络IP,内存,cpu,磁盘及分区,启动项,…

C++ 用红黑树封装map/set

前言 一、源码结构分析 二、模拟实现map/set 2.1 套上KeyOfT 2.2 普通迭代器实现 2.3 const迭代器实现 2.4 解决key不能修改的问题 2.5 map的[]实现 2.6 map/set以及红黑树源码 2.6.1 RBTree.h 2.6.2 set.h 2.6.3 map.h 总结 前言 之前的文章讲解了红黑树的具体实…

量子计算未来的潜力和挑战

据麦肯锡预测&#xff0c;到 2035 年或 2040 年&#xff0c;量子计算市场规模可能增长至约 800 亿美元。目前&#xff0c;许多量子比特技术正竞相成为首台通用、无差错量子计算机的基础&#xff0c;但仍面临诸多挑战。 我们将探讨量子计算的未来前景、潜力&#xff0c;以及它对…

五笔输入法学习的抉择:86版 or 98版?(一场关于效率与传承的思辨)

新开直接98&#xff0c;纯粹高开&#xff1b;老版过渡艰辛自知&#x1f60b;。 笔记模板由python脚本于2025-04-14 19:22:22创建&#xff0c;本篇笔记适合喜好汉字衷情母语的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;…

为您的 Web 应用选择最佳文档阅读器

为显示选择合适的文档查看器是开发 Web 应用过程中至关重要的一步。文档查看器应能在提供功能性的同时&#xff0c;确保用户体验的流畅性。 开发人员必须评估多种因素&#xff0c;以确保效率、性能和兼容性。本文将帮助您了解影响用户文档浏览体验成功与否的关键指标。 渲染质…

微服务之protobuf:下载、语法和使用一站式教程

基本介绍 Protobuf全称 Protocol Buffer&#xff0c;是 Google 公司于2008年开源的一种语言无关、平台无关、可扩展的用于序列化结构化数据——类似于XML&#xff0c;但比XML更小、更快、更简单&#xff0c;它可用于&#xff08;数据&#xff09;通信协议、数据存储等。你只需…

Ollama调用多GPU实现负载均衡

文章目录 &#x1f4ca; 背景说明&#x1f6e0;️ 修改 systemd 服务配置1. 配置文件路径2. 编辑服务文件2. 重新加载配置并重启服务3. 验证配置是否成功 &#x1f4c8; 应用效果示例1. 调用单个70b模型2. 调用多个模型&#xff08;70b和32b模型&#xff09; 总结&#x1f4cc;…

WebRTC实时通话EasyRTC嵌入式音视频通信SDK,构建智慧医疗远程会诊高效方案

一、方案背景 当前医疗领域&#xff0c;医疗资源分布不均问题尤为突出&#xff0c;大城市和发达地区优质医疗资源集中&#xff0c;偏远地区医疗设施陈旧、人才稀缺&#xff0c;患者难以获得高质量的医疗服务&#xff0c;制约医疗事业均衡发展。 EasyRTC技术基于WebRTC等先进技…