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

目录

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.mfbz.cn/a/66918.html

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

相关文章

【Kubernetes】Kubernetes之Pod详解

Pod 一、 Pod1. Pod 基础概念2. 在 Kubrenetes 集群中 Pod 使用方式2.1 pasue 容器2.2 kubernetes 中的 pause 容器提供的功能 3. Pod 的概念和结构组成4. Pod 的分类5. Pod 容器的分类5.1 基础容器&#xff08;infrastructure container&#xff09;5.2 初始化容器&#xff08…

外部链接跳转到vue项目传递参数实现单点登录

1、问题背景描述&#xff1a; 我有一个困扰了很久项目需求&#xff0c;前台门户用的MVC&#xff0c;前台登录之后需要能点击某个按钮就能进入后台vue开发的前端项目&#xff0c;不需要重新登录。这个需求中mvc项目相对于vue项目来说是外部链接&#xff0c;他要跳转到vue项目&a…

无涯教程-Perl - getnetbyname函数

描述 此函数返回由NAME指定的网络信息(在列表context中)($name,$aliases,$addrtype,$net) 语法 以下是此函数的简单语法- getnetbyname NAME返回值 此函数在错误时返回undef,否则在标量context中返回网络地址,在错误时返回空列表,否则在列表context中返回网络记录(名称,别…

山东布谷科技直播程序源码使用Redis进行服务器横向扩展

当今&#xff0c;直播程序源码平台作为新媒体时代主流&#xff0c;受到了世界各地人民的喜爱&#xff0c;这也使得直播程序源码平台用户数量的庞大&#xff0c;也难免会出现大量用户同时访问服务器&#xff0c;使服务器过载的情况&#xff0c;当服务器承受不住的时候&#xff0…

CSS元素的显示模式

1、现在我想做成小米左侧边栏这样的效果&#xff0c;该怎么做呢&#xff1f; 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式&#xff1a; 5、用人进行划分可以分为男人和女人&#xff0c;根据男人和女人的特性进行相应的…

扫雷(超详解+全部码源)

C语言经典游戏扫雷 前言一.游戏规则二.所需文件三.创建菜单四.游戏核心内容实现1.创建棋盘2.打印棋盘3.布置雷4.排查雷5.game()函数具体实现 五.游戏运行实操六.全部码源 前言 &#x1f600;C语言实现扫雷是对基础代码能力的考察。通过本篇文章你将学会如何制作出扫雷&#xff…

8月11日|CSA研讨会:国标要点解读《信息安全技术 个人信息处理中告知和同意实施指南》

随着网络与数据科技的进步&#xff0c;个人信息在AIGC、元宇宙世界等产业中扮演着愈发关键的角色。如何实施告知并取得个人主体同意是个人信息处理的基本前提&#xff0c;对于企业等处理者而言尤为重要。《个人信息保护法》规定了知情同意的原则和一般规则&#xff0c;但仍有不…

清除浮动(clearfix)是什么,如何实现?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 清除浮动是什么&#xff1f;⭐ 清除浮动的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些…

【Spring】Bean的作用域和生命周期

目录 一、引入案例来探讨Bean的作用域 二、Bean的作用域 2.1、Bean的6种作用域 2.2、设置Bean的作用域 三、Spring的执行流程 四、Bean的声明周期 1、生命周期演示 一、引入案例来探讨Bean的作用域 首先我们创建一个User类&#xff0c;定义一个用户信息&#xff0c;在定义…

【图像去噪的滤波器】非局部均值滤波器的实现,用于鲁棒的图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

软考高项(八)项目整合管理 ★重点集萃★

&#x1f451; 个人主页 &#x1f451; &#xff1a;&#x1f61c;&#x1f61c;&#x1f61c;Fish_Vast&#x1f61c;&#x1f61c;&#x1f61c; &#x1f41d; 个人格言 &#x1f41d; &#xff1a;&#x1f9d0;&#x1f9d0;&#x1f9d0;说到做到&#xff0c;言出必行&am…

一条sql语句在mysql中如何执行(查询+更新)

文章目录 一 MySQL 基础架构1.1 MySQL 基本架构1.2 Server 层基本组件介绍1) 连接器2) 查询缓存(MySQL 8.0 版本后移除)3) 分析器4) 优化器5) 执行器 二 语句分析2.1 查询语句2.2 更新语句为什么要用两个日志模块&#xff0c;用一个日志模块不行吗?为什么必须有“两阶段提交”…

初识Java集合框架

前言 在大多数情况下&#xff0c;你常常会看到《C数据结构》类似的书籍&#xff0c;很多人可能会认为数据结构是一门依赖语言的学科&#xff0c;有了语言才可能有数据结构&#xff0c;其实这里需要纠正的是&#xff0c; 数据结构(Data Structure)是计算机存储、组织数据的方式…

Ubuntu类IOS主题设置

1.依次执行下面三条命令&#xff1a; sudo apt install gnome-shell-extensions sudo apt install gnome-tweak-tool sudo apt install chrome-gnome-shell2.下载主题&#xff0c;也是命令&#xff1a; git clone <https://github.com/qingchendelaike/GNOME-OSX-II-Theme…

Unity之获取用户地理位置

1.直接利用三方API获取&#xff1a; 1.1 利用bilibili的api 【未知稳定性】 public void Awake() {StartCoroutine(GetLocationInfoNew());}/// <summary>/// 利用bilibili的接口通过ip直接获取城市信息/// </summary>IEnumerator GetLocationInfoNew() {//UnityW…

python优雅地爬虫

申明&#xff1a;仅用作学习用途&#xff0c;不提供任何的商业价值。 背景 我需要获得新闻&#xff0c;然后tts&#xff0c;在每天上班的路上可以听一下。具体的方案后期我也会做一次分享。先看我喜欢的万能的老路&#xff1a;获得html内容-> python的工具库解析&#xff0…

Linux常见命令

新建标签页 (gitee.com)尹相辉 (yinxianghui66) - Gitee.com新建标签页 (gitee.com) 文章目录 文章目录 一、Linux常见命令 1.ls 2.cd 目录名 3.pwd 4.touch 文件名 5.echo 字符串->目标文件 6.cat 文件名 7.man 8.vim 文件名 9.mkdir 目录名 10.rm 文件名 11.mv 源…

【贪心算法】leetcode刷题

贪心算法无固定套路。 核心思想&#xff1a;先找局部最优&#xff0c;再扩展到全局最优。 455.分发饼干 两种思路&#xff1a; 1、从大到小。局部最优就是大饼干喂给胃口大的&#xff0c;充分利用饼干尺寸喂饱一个&#xff0c;全局最优就是喂饱尽可能多的小孩。先遍历的胃口&a…

zadig安装驱动潜在风险与解决策略

zadig安装驱动潜在风险与解决策略 ✨没事不要闲着乱打驱动&#xff0c;能正常使用的情况下&#xff0c;不要轻易或随意去乱打驱动&#xff0c;可能会导致新的驱动对已有的设备不兼容的问题。✨&#x1f530;特别说明&#xff1a;本文介绍的方法&#xff0c;并不能包治百病&…

【MATLAB第67期】# 源码分享 | 基于MATLAB的morris全局敏感性分析

【MATLAB第67期】# 源码分享 | 基于MATLAB的morris全局敏感性分析 一、代码展示 clear all npoint100;%在分位数超空间中要采样的点数(计算次数iternpoint*(nfac1) nfac20;%研究函数的不确定因素数量 [mu, order] morris_sa1((x)test_function(x), nfac, npoint)for t1:size…