【二叉树】刷题二(以递归写法为主)

news2024/9/29 21:20:23

在这里插入图片描述

617. 合并二叉树

在这里插入图片描述

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        root = TreeNode()
        if not root1 and not root2:
            return
        elif root1 and not root2:
            root = root1
        elif not root1 and root2:
            root = root2
        elif root1 and root2:
            root.val = root1.val + root2.val
            root.left = self.mergeTrees(root1.left, root2.left)
            root.right  = self.mergeTrees(root1.right,root2.right)
        return root

700.二叉搜索树中的搜索

在这里插入图片描述

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if not root or root.val==val:
            return root
        if root.val<val:
            return self.searchBST(root.right,val)
        elif root.val>val:
            return self.searchBST(root.left,val)

98.验证二叉搜索树

在这里插入图片描述

class Solution:
    def __init__(self):
        self.valid = float('-inf')
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        # 中序遍历的结果一定是从小到大,否则为false
        if not root:
            return True
        left = self.isValidBST(root.left)
        if self.valid<root.val:
            self.valid = root.val
        else:
            return False
        right = self.isValidBST(root.right)
        return left and right

530.二叉搜索树的最小绝对差

在这里插入图片描述

class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        # 先中序遍历,在找到差值最小的两个值之间。因为二插搜索树的中序遍历是从小到大,所以两两找就可以找到差值最小值了。
        res = []
        def dfs(root):
            if not root:
                return 
            dfs(root.left)
            res.append(root.val)
            dfs(root.right)
        dfs(root)
        min_value = res[-1]
        for i in range(len(res)-1):
            min_value = min(min_value,res[i+1]-res[i])
        return min_value

501.二叉搜索树中的众数

在这里插入图片描述

class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        # 先中序遍历,在按照counter的次数进行排序,返回计数最大的几个值。
        res = []
        def dfs(root):
            if not root:
                return 
            dfs(root.left)
            res.append(root.val)
            dfs(root.right)
        dfs(root)
        final_statics = collections.Counter(res)
        sorted_value = sorted(final_statics.items(),key=lambda x:x[-1],reverse = True)
        res = []
        for key,value in sorted_value:
            if value == sorted_value[0][1]:
                res.append(key)
        return res

236. 二叉树的最近公共祖先

在这里插入图片描述
详细看代码随想录中本题题解
思路:

  • 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
  • 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
  • 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。

如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
在这里插入图片描述

在这里插入图片描述
递归三部曲:
1、确定递归函数返回值以及参数

lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

2、确定终止条件
遇到空的话,因为树都是空了,所以返回空。
那么我们来说一说,如果 root == q,或者 root == p,说明找到 q p ,则将其返回,这个返回值,后面在中节点的处理过程中会用到,那么中节点的处理逻辑,下面讲解。

if (root == q || root == p || root == NULL) return root;

3、确定单层递归逻辑 (是遍历一边?还是遍历整颗树?)

PS:
在这里插入图片描述
本题中,在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。

在这里插入图片描述
如果left 和 right都不为空,说明此时root就是最近公共节点。这个比较好理解
如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然。


class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

        if p==root or  q==root or not root:  # 要么返回p,要么返回q,要么返回空。
            return root
        left = self.lowestCommonAncestor(root.left,p,q)
        right = self.lowestCommonAncestor(root.right,p,q)
        if left and not right:
            return left    # 如果左存在,右与空,则说明左侧中包含p/q,先找到的本身就是最近祖先
        if right and not left:
            return right   # 如果左为空,右存在,则说明右侧中包含p/q,先找到的本身就是最近祖先
        if left and right:
            return root   # 这里注意返回的是root,也就是祖先,而不是返回left/right

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

在这里插入图片描述
在这里插入图片描述

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:    # 没找到删除的节点,遍历到空节点直接返回了
            return root 
        if root.val == key:  # 找到删除的节点
            if root.right and not root.left:   # 删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
                return root.right
            elif root.left and not root.right: # 删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
                return root.left
            elif root.left and root.right:   # 既有左孩子,也有由孩子的情况
                cur = root.right
                while cur.left is not None:   # 找到右子树最左下角的一个
                    cur = cur.left
                cur.left = root.left
                return root.right
            else:          # 左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
                return None

        if root.val>key: # left
            root.left = self.deleteNode(root.left,key)
        if root.val<key:
            root.right = self.deleteNode(root.right,key)
        return root

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

在这里插入图片描述

class Solution:
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
       

        if not root:
            subTree = TreeNode(val = val)
            return subTree
        
        if root.val>val:
            root.left = self.insertIntoBST(root.left,val)   # 关键点:注意返回值要接住
        if root.val<val:
            root.right = self.insertIntoBST(root.right,val)  # 关键点:注意返回值要接住
        return root

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

在这里插入图片描述
在这里插入图片描述

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:    # 没找到删除的节点,遍历到空节点直接返回了
            return root 
        if root.val == key:  # 找到删除的节点
            if root.right and not root.left:   # 删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
                return root.right
            elif root.left and not root.right: # 删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
                return root.left
            elif root.left and root.right:   # 既有左孩子,也有由孩子的情况
                cur = root.right
                while cur.left is not None:   # 找到右子树最左下角的一个
                    cur = cur.left
                cur.left = root.left
                return root.right
            else:          # 左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
                return None

        if root.val>key: # left
            root.left = self.deleteNode(root.left,key)
        if root.val<key:
            root.right = self.deleteNode(root.right,key)
        return root

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

在这里插入图片描述

class Solution:
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
       

        if not root:
            subTree = TreeNode(val = val)
            return subTree
        
        if root.val>val:
            root.left = self.insertIntoBST(root.left,val)   # 关键点:注意返回值要接住
        if root.val<val:
            root.right = self.insertIntoBST(root.right,val)  # 关键点:注意返回值要接住
        return root

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

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

相关文章

AD21原理图的高级应用(一)端口的应用

&#xff08;一&#xff09;端口的应用 1.放置端口2.自动给端口添加页码 说明&#xff0c;博主的AD版本是AD21&#xff0c;所有的工程都基于AD21&#xff0c;虽然AD软件几乎不存在版本兼容性问题&#xff0c;但还是建议大家使用对应版本的软件来学习。 资料仅供学习使用。 1.…

013 怎么查看自己电脑的wifi密码

方法一&#xff1a;查看当前电脑连接的无线密码 步骤1&#xff1a; 打开windows命令行窗口&#xff0c;输入&#xff1a;ncpa.cpl 快速打开“控制面板”中的“网络连接”&#xff0c;如下图&#xff1a; 步骤2&#xff1a; 右键&#xff0c;打开“状态” 步骤3&#xff1a;…

Pearson correlation皮尔逊相关性分析

在参数检验的相关性分析方法主要是皮尔逊相关&#xff08;Pearson correlation&#xff09;。既然是参数检验方法&#xff0c;肯定是有一些前提条件。皮尔逊相关的前提是必须满足以下几个条件&#xff1a; 变量是连续变量&#xff1b;比较的两个变量必须来源于同一个总体&…

瓦瑟斯坦距离、收缩映射和现代RL理论

Wasserstein Distance, Contraction Mapping, and Modern RL Theory | by Kowshik chilamkurthy | Medium 一、说明 数学家们在考虑一些应用的情况下探索的概念和关系 - 几十年后成为他们最初从未想象过的问题的意想不到的解决方案。 黎曼的几何学只是出于纯粹的原因才被发现的…

Abaqus 导出单元刚度矩阵和全局刚度矩阵

Abaqus 导出单元刚度矩阵和全局刚度矩阵 首次创建&#xff1a;2023.7.29 最后更新&#xff1a;2023.7.29 如有什么改进的地方&#xff0c;欢迎大家讨论&#xff01; 详细情况请查阅&#xff1a;Abaqus Analysis User’s Guide 一、Abaqus 导出单元刚度矩阵 1.生成单元刚度矩阵…

Kafka原理剖析

一、简介 Kafka是一个分布式的、分区的、多副本的消息发布-订阅系统&#xff0c;它提供了类似于JMS的特性&#xff0c;但在设计上完全不同&#xff0c;它具有消息持久化、高吞吐、分布式、多客户端支持、实时等特性&#xff0c;适用于离线和在线的消息消费&#xff0c;如常规的…

安装Anaconda3和MiniConda3

MiniConda3官方版是一款优秀的Python环境管理软件。MiniConda3最新版只包含conda及其依赖项如果您更愿意拥有conda以及超过720个开源软件包&#xff0c;请安装Anaconda。MiniConda3官方版还是一个开源的软件包管理系统和环境管理系统&#xff0c;能够帮助用户安装多个版本的软件…

Android高德地图定位实现签到打卡功能(全网最详细+收藏)

前言 本章根据高德地图API&#xff0c;实现打卡签到功能。用到了定位SDK 和地图SDK、覆盖物。打卡范围图形可以支持多种形状&#xff0c;如&#xff1a;圆形、长方形、多边形。 核心逻辑&#xff1a; 获取当前定位信息&#xff0c;然后通过Marker绘制小图标进行展示&a…

IO流(1)-字符流与字节流

1. I/O流前置知识 在讲解IO流之前&#xff0c;需要先说明几个小知识点&#xff1a; &#xff08;1&#xff09;bit 是最小的二进制单位&#xff0c;是计算机的操作部分&#xff0c;取值0或1。 &#xff08;2&#xff09;Byte&#xff08;字节&#xff09;是计算机操作数据的…

PayPal:全球金融科技领域当之无愧的巨无霸

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 全球最大的金融科技公司之一PayPal(PYPL)将于2023年8月2日发布其2023年第二季度的财报。多年以来该公司一直在革新数字汇款和收款方式&#xff0c;并提高数百万客户的生活质量。此外&#xff0c;PayPal的各种工具也为企业…

Java文件操作与流处理

文章目录 一、文件1.1 文件的概念1.2 文件的组织结构1.3 绝对路径和相对路径 二、文件操作File类2.1 属性和常用方法2.2 使用案例 三、字节流和字符流3.1 InputStream 和 FileInputStream3.2 使用 Scanner 读取字符3.2 OutputStream 和 FileOutputStream3.3 Reader 和 FileRead…

【每日一题】141. 环形链表

【每日一题】141. 环形链表 【每日一题】141. 环形链表题目描述解题思路 【每日一题】141. 环形链表 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环…

深入理解C++命名空间

文章目录 1. 命名空间的概念2. 解决命名冲突3. 嵌套命名空间4. 使用命名空间别名总结 在C编程中&#xff0c;命名空间&#xff08;Namespace&#xff09;是一种非常有用的工具&#xff0c;它可以帮助我们组织和管理代码&#xff0c;避免命名冲突。本文将深入介绍C命名空间的概念…

WIZnet W5500-EVB-Pico树莓派入门教程(一)

概述 W5500-EVB-Pico是基于树莓派RP2040和完全硬连线TCP/IP控制器W5500的微控制器开发板-基本上与树莓派Pico板相同&#xff0c;但通过W5500芯片增加了以太网功能。 板载资源 RP2040是Raspberry Pi的首款微控制器。它将我们的高性能、低成本和易用性的标志性价值观带入微控制器…

【Android安全】Embedded Trace Microcell模块

ETM: Embedded Trace Macrocell, hardware unit responsible to generate hardware instruction trace. ETM模块用于在硬件层面实现instruction trace&#xff0c;可用于辅助逆向分析。 使用教程&#xff1a; https://mcuoneclipse.com/2016/11/05/tutorial-getting-etm-inst…

如何集成 Milvus 和 LangChain?

以下代码集成了 Milvus 和 LangChain: class VectorStore(ABC):"""Interface for vector stores.""" @abstractmethoddef add_texts(self,texts: Iterable[str],metadatas: Optional[List[dict]] = None, kwargs:Any,) ->List[str]: &…

[STL]详解list模拟实现

[STL]list模拟实现 文章目录 [STL]list模拟实现1. 整体结构总览2. 成员变量解析3. 默认成员函数构造函数1迭代器区间构造函数拷贝构造函数赋值运算符重载析构函数 4. 迭代器及相关函数迭代器整体结构总览迭代器的模拟实现begin函数和end函数begin函数和end函数const版本 5. 数据…

Spring源码(四)— 创建BeanDefinition

在第一章序言的图示中有提到&#xff0c;Spring中的配置文件都是通过各种的BeanDefinition来进行解析&#xff0c;并且支持不同类型的文件进行扩展。所以在创建完DefaultListableBeanFactory后&#xff0c;会通过BeanDefinition来解析传入的xml配置文件。 loadBeanDefinitions…

如何建立ftp server?快解析内网穿透实现外网直接访问

serveru是一款由Rob Beckers开发的获奖的ftp服务器软件&#xff0c;全称为&#xff1a;serv-u ftp server&#xff0c;它功能强大又易于使用。ftp服务器用户通过它用ftp协议能在internet上共享文件。serv-u不仅100%遵从通用ftp标准&#xff0c;也包括众多的独特功能可为每个用户…

常用直线模组的类型

目前&#xff0c;直线模组的应用非常广泛&#xff0c;而且直线模组的种类也有很多可以满足每个行业的应用要求&#xff0c;那么常见的直线模组类型有哪些&#xff0c;大家知道吗&#xff1f; 1、全封闭滚珠丝杆直线模组&#xff1a; 在半封闭式的基础上增加了不锈钢带防尘结构…