【递归算法实践】验证二叉搜索树

news2024/11/23 18:39:30

目录

1. 递归算法

2. 递归实现验证二叉搜索树

3. 递归解法的实现逻辑

4. 递归实现的实例分析


1. 递归算法

递归是一种通过函数自身调用来解决问题的算法,它可以使代码更加简洁和优雅,同时也能够解决许多复杂的问题。在递归中,函数会不断地调用自身来解决一个更小的问题,直到达到基本情况为止。

递归算法(recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。

2. 递归实现验证二叉搜索树

题目:

https://leetcode.cn/problems/validate-binary-search-tree/

https://leetcode.com/problems/validate-binary-search-tree/

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

代码实现:

from typing import Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:

    def __init__(self) -> None:
        self.pre = float("-inf")

    # inorder traversal
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if root is None :
            return True
        # 一直递进左子树中,直到遇到 None,这时候发生第一次的回归,
        # 然后执行下面几行代码,即进行值的判断,并且递进到右子树中,
        # 接着按照递进的反方向一层一层的回归
        if not self.isValidBST(root.left):
            return False
        if root.val <= self.pre:
            return False
        self.pre = root.val
        return self.isValidBST(root.right)

if __name__ == "__main__":
    solution = Solution()

    # a = TreeNode(4)
    root = TreeNode(0)
    # c = TreeNode(3)

    # root.left = a
    # root.right = c

    result = solution.isValidBST(root)
    print(result)

3. 递归解法的实现逻辑

`isValidBST` 方法中,先判断当前节点是否为 None,如果是则返回 True,表示当前子树是一个有效的 BST。接着,递归判断左子树是否为 BST,如果不是则返回 False。然后,判断当前节点的值是否小于等于上一个节点的值 `pre`,如果小于等于则返回 False。最后,将当前节点的值赋值给 `pre`,递归判断右子树是否为 BST,如果不是则返回 False。

如果以上条件都满足,则该二叉树是一个有效的 BST,返回 True。

在 `isValidBST` 方法中,如果左子树或右子树不是 BST,则返回 False,而不是返回 True,是因为在判断一个二叉树是否为 BST 时,只要发现它的左子树或右子树不是 BST,就可以确定该二叉树不是 BST,不需要再继续遍历下去了。

如果在左子树或右子树中发现了一个不符合 BST 的节点,那么它的父节点及其祖先节点都不可能是 BST,因为 BST 的定义要求左子树的所有节点都小于根节点,右子树的所有节点都大于根节点。因此,如果左子树或右子树不是 BST,就可以直接返回 False,不需要再继续遍历下去了,这样可以提高程序的效率。

4. 递归实现的实例分析

`isValidBST`函数是一个验证二叉搜索树的函数。下面使用一个例子来逐步解释递归的执行流程和代码实现思路。

假设我们有以下二叉树:

```
5
/ \\
1 7
/ \\
6 8
```

我们首先调用`isValidBST`函数,传入根节点`5`。由于`root`不为空,我们继续执行函数。由于`root`有左子节点`1`,我们递归调用`isValidBST`函数,传入`1`作为参数。由于`1`没有左子节点或右子节点,我们直接返回`True`。此时,我们回到了根节点`5`的函数调用。

由于`root`有左子节点,我们刚刚递归调用了`isValidBST`函数,它会返回`True`。我们继续执行函数,检查`root`的值是否大于前一个节点的值。由于这是第一个节点,前一个节点的值为负无穷,所以这个条件满足。我们将`pre`的值设置为`5`,然后继续执行函数。

由于`root`有右子节点`7`,我们递归调用`isValidBST`函数,传入`7`作为参数。由于`7`有左子节点`6`,我们继续递归调用`isValidBST`函数,传入`6`作为参数。由于`6`没有左子节点或右子节点,我们直接返回`True`。此时,我们回到了节点`7`的函数调用。

由于`7`的左子节点`6`已经处理完毕,我们继续执行函数,检查`root`的值是否大于前一个节点的值。由于`7`大于`5`,这个条件满足。我们将`pre`的值设置为`7`,然后继续执行函数。

由于`7`有右子节点`8`,我们递归调用`isValidBST`函数,传入`8`作为参数。由于`8`没有左子节点或右子节点,我们直接返回`True`。此时,我们回到了节点`7`的函数调用。

由于`root`的右子树已经处理完毕,我们回到了根节点`5`的函数调用。由于根节点`5`的左子树和右子树都已经处理完毕,且满足二叉搜索树的定义,所以整个函数返回`True`,表示这棵二叉树是一棵合法的二叉搜索树。

这段代码的实现思路是,对于每个节点,都检查它是否大于前一个节点的值。由于二叉搜索树的中序遍历是有序的,前一个节点的值应该小于当前节点的值。如果出现了前一个节点的值大于当前节点的值的情况,说明这棵二叉树不是一棵合法的二叉搜索树。

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

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

相关文章

【Windows10下启动RocketMQ报错:找不到或无法加载主类 Files\Java\jdk1.8.0_301\lib\dt.jar】解决方法

Windows10下启动RocketMQ报错&#xff1a;找不到或无法加载主类 一、问题产生二、产生原因三、解决办法 一、问题产生 参考RocketMQ Github官网上的说明&#xff0c;下载rocketmq-all-5.1.3-bin-release.zip&#xff0c;解压配置环境变量后&#xff0c;执行如下命令&#xff1a…

基于2.4G RF开发的无线游戏手柄解决方案

平时喜欢玩游戏的朋友&#xff0c;肯定知道键鼠在某些类型的游戏适配和操作方面&#xff0c;不如手柄。作为一个游戏爱好者&#xff0c;还得配上一个游戏手柄才行。比如动作和格斗、体育游戏&#xff0c;由于手柄更合理的摇杆位置和按键布局&#xff0c;操作起来也是得心应手。…

6.pip简介,第三方库的安装

引言 使用过Visual Studio的小伙伴可能对npm不陌生&#xff0c;没错&#xff0c;pip与npm的功能是一样的。 首先要知道&#xff0c;Python这门语言拥有着丰富的标准库以及先辈们开发的各种功能强大的第三方库。而今天我们主要学习的呢就是关于Python中的包管理工具。它是Pytho…

图像的镜像变换之c++实现(qt + 不调包)

1.基本原理 1.水平镜像变化 设图像的宽度为width&#xff0c;则水平镜像变化的映射关系如下&#xff1a; 2.垂直镜像变化 设图像的宽度为height&#xff0c;则垂直镜像变化的映射关系如下&#xff1a; 2.代码实现&#xff08;代码是我以前自学图像处理时写的&#xff0c;代码很…

VS Code安装使用教程

目录 1. VS Code是什么&#xff1f; 2. VS Code的下载和安装 下载&#xff1a; 安装&#xff1a; 2.2 环境的介绍 3. VS Code配置C/C开发环境 3.1 下载和配置MinGW-w64编译器套件 下载&#xff1a; 配置&#xff1a; 3.2 安装C/C插件 3.3 重启VSCode 4. 在VSCode上编…

如何快速创建学校录取查询系统?

作为一名老师&#xff0c;我深知学生及家长们对于录取情况的关注和期待。因此&#xff0c;学校公布录取情况表是非常重要的一项工作。在这篇文章中&#xff0c;我将分享学校公布录取情况表的步骤和流程&#xff0c;帮助大家更好地了解录取情况。 老教师一般是使用易查分来让家…

坤简炫酷的JQuery轮播图插件

介绍&#xff1a; 找到了一个炫酷的JQuery轮播图插件&#xff0c;只需要配置三四行代码就可以实现很多二维三维炫酷的切换效果。 视频效果及教程&#xff1a; https://www.bilibili.com/video/BV1Fu4y1d776/ 代码&#xff1a; https://github.com/w-x-x-w/AwesomeWeb 使用…

[软件工具][原创]OCR识字找图关键词找图以文搜图工具使用教程

OCR识字找图工具功能简介&#xff1a; 当你有一批图片但是想提取图片里面包含关键词的的图片&#xff0c;以前都是手工肉眼打开去找&#xff0c;其实这个大可不必&#xff0c;现在只需输入关键词&#xff0c;软件会自动搜索所有图片&#xff0c;只要包含指定关键词就会复制或者…

【雕爷学编程】Arduino动手做(199)---8x32位WS2812B全彩屏模块

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

【12】Git工具 协同工作平台使用教程 【Gitee】【腾讯工蜂】

tips&#xff1a;少量的git安装和使用教程&#xff0c;更多讲快速使用上手Gitee和工蜂平台 一、准备工作 1、下载git Git - Downloads (git-scm.com) 找到对应操作系统&#xff0c;对应版本&#xff0c;对应的位数 下载后根据需求自己安装&#xff0c;然后用git --version验…

从R调用python并将即时输出到cons

我使用R命令从R运行python脚本&#xff1a; system(python test.py)但我的打印报表测试.py在python程序完成之前不要出现在R控制台中。我想查看print语句&#xff0c;因为python程序正在R中运行。我也尝试过sys.stdout.write()&#xff0c;但结果是一样的。非常感谢您的帮助。…

Linux系统中的自旋锁(两幅图清晰说明)

总结&#xff1a; 多CPU下的自旋锁采取的是忙等待&#xff08;原地打转&#xff09;机制&#xff0c;虽然忙等待的线程占用了它所在的cpu&#xff0c;但其他线程仍可放到其他CPU上执行。所以自旋锁上锁和解锁之间的临界区代码要尽量的短&#xff0c;最好不要超过5行&#xff0c…

【MySQL】汇总数据

目录 一、聚集函数 1.AVG()参数 2.COUNT()函数 3.MAX()函数 4.MIN()函数 5.SUM()函数 二、聚集不同值 三、组合聚集函数 一、聚集函数 聚集函数&#xff1a;运行在行组上&#xff0c;计算和返回单个值的函数&#xff0c;用来汇总数据。 SQL聚集函数 AVG()返回某列的平…

【100天精通python】Day30:使用python操作数据库_数据库基础入门

专栏导读 专栏订阅地址&#xff1a;https://blog.csdn.net/qq_35831906/category_12375510.html 1 数据库基础知识介绍 1.1 什么是数据库&#xff1f; 数据库是一个结构化存储和组织数据的集合&#xff0c;它可以被有效地访问、管理和更新。数据库的目的是为了提供一种可靠的…

go-admin解读1goLand debug 快捷编译重启配置

** goLand debug &快捷编译重启配置 **

一文读懂ISO27701

引言 隐私暴露&#xff0c;大数据营销杀熟、骚扰信息不断……越来越多的数据泄露与威胁影响全球人类的安宁生活。在此背景下&#xff0c;各个国家、地区纷纷出台相关法律法规&#xff0c;对数据安全与隐私保护相关问题进行严格规范与引导。目前常见的有中国的个人信息保护法、…

Three.js 设置模型材质纹理贴图和修改材质颜色,材质透明度,材质网格

相关API的使用&#xff1a; 1 traverse &#xff08;模型循环遍历方法&#xff09; 2. THREE.TextureLoader&#xff08;用于加载和处理图片纹理&#xff09; 3. THREE.MeshLambertMaterial&#xff08;用于创建材质&#xff09; 4. getObjectByProperty&#xff08;通过材…

[保研/考研机试] KY180 堆栈的使用 吉林大学复试上机题 C++实现

题目链接&#xff1a; 堆栈的使用_牛客题霸_牛客网 描述 堆栈是一种基本的数据结构。堆栈具有两种基本操作方式&#xff0c;push 和 pop。其中 push一个值会将其压入栈顶&#xff0c;而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。 输入描述&#xff1a; 对于…

Flink窗口分类简介及示例代码

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. 流式计算2. 窗口3. 窗口的分类◆ 基于时间的窗口&#xff08;时间驱动&#xff09;1) 滚动窗口&#xff08;Tumbling Windows&#xff09;2) 滑动窗口&#xff08;Sliding Windows&…

发现 Kubernetes 集群受到攻击

Aqua Security 的研究团队 Aqua Nautilus 发现数百个组织的 Kubernetes 集群受到攻击。 这位云原生安全专家宣布&#xff0c;一项为期三个月的调查显示&#xff0c;属于 350 多个组织、开源项目和个人的 Kubernetes 集群可公开访问且不受保护。 一个值得注意的集群子集与大型…