python-leetcode 42.验证二叉搜索树

news/2025/2/25 22:23:00/

题目:

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

有效二叉搜索树:

1.节点的左子树只包含小于当前节点的树

2.节点的右子树只包含大于当前节点的树

3.所有左子树和右子树自身必须也是二叉搜索树

方法一:递归

如果该二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也为二叉搜索树。

设计一个递归函数 helper(root, lower, upper) 来递归判断,函数表示考虑以 root 为根的子树,判断子树中所有节点的值是否都在 (l,r) 的范围内(注意是开区间)。如果 root 节点的值 val 不在 (l,r) 的范围内说明不满足条件直接返回,否则我们要继续递归调用检查它的左右子树是否满足,如果都满足才说明这是一棵二叉搜索树。

根据二叉搜索树的性质,在递归调用左子树时,我们需要把上界 upper 改为 root.val,即调用 helper(root.left, lower, root.val),因为左子树里所有节点的值均小于它的根节点的值。同理递归调用右子树时,我们需要把下界 lower 改为 root.val,即调用 helper(root.right, root.val, upper)。

函数递归调用的入口为 helper(root, -inf, +inf), inf 表示一个无穷大的值。

class TreeNode(object):def __init__(self, x):self.val = xself.left = Noneself.right = Noneclass Solution(object):def isValidBST(self, root):def helper(node, lower=float('-inf'), upper=float('inf')):# 如果节点为空,说明已经遍历到叶子节点或空树,返回 Trueif not node:return Trueval = node.val# 当前节点的值必须大于 lower 且小于 upperif val <= lower or val >= upper:return False# 递归检查右子树,将当前节点的值作为新的 lowerif not helper(node.right, val, upper):return False# 递归检查左子树,将当前节点的值作为新的 upperif not helper(node.left, lower, val):return Falsereturn Truereturn helper(root)

时间复杂度:O(n)其中 n 为二叉树的节点个数。在递归调用的时候二叉树的每个节点最多被访问一次

空间复杂度:O(n)


方法二:中序遍历

二叉搜索树「中序遍历」得到的值构成的序列一定是升序的,这启示我们在中序遍历的时候实时检查当前节点的值是否大于前一个中序遍历到的节点的值即可。如果均大于说明这个序列是升序的,整棵树是二叉搜索树,否则不是

中序遍历是二叉树的一种遍历方式,它先遍历左子树,再遍历根节点,最后遍历右子树。而我们二叉搜索树保证了左子树的节点的值均小于根节点的值,根节点的值均小于右子树的值,因此中序遍历以后得到的序列一定是升序序列

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def isValidBST(self, root):""":type root: Optional[TreeNode]:rtype: bool"""stack=[]  #用于模拟递归的栈,用来存储待处理的节点inorder=float('-inf') #用于记录前一个访问的节点值。初始值为负无穷while stack or root: #栈不为空或者当前节点不为空while root:  #当前节点和所有左子树节点压入栈stack.append(root)root=root.leftroot=stack.pop()  #从栈中弹出一个节点
#之前压入的是当前节点和所有左子树节点,所以栈顶的节点是当前树的最左节点if root.val<=inorder:return Falseinorder=root.val #更新 inorder 为当前节点的值root=root.right #将当前节点的右子树作为下一个要处理的节点return True

时间复杂度:O(n)其中 n 为二叉树的节点个数。在递归调用的时候二叉树的每个节点最多被访问一次

空间复杂度:O(n)

源自扣官方题解
 


http://www.ppmy.cn/news/1574906.html

相关文章

DeepSeek 15天指导手册——从入门到精通 PDF(附下载)

DeepSeek使用教程系列--DeepSeek 15天指导手册——从入门到精通pdf下载&#xff1a; https://pan.baidu.com/s/1PrIo0Xo0h5s6Plcc_smS8w?pwd1234 提取码: 1234 或 https://pan.quark.cn/s/2e8de75027d3 《DeepSeek 15天指导手册——从入门到精通》以系统化学习路径为核心&…

SpringBoot+Vue+微信小程序的猫咖小程序平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在当下这个高速发展的时代&#xff0c;网络科技正以令人惊叹的速度不断迭代更新。从 5G …

七.智慧城市数据治理平台架构

一、整体架构概览 智慧城市数据治理平台架构描绘了一个全面的智慧城市数据治理平台&#xff0c;旨在实现城市数据的统一管理、共享和应用&#xff0c;为城市运行、管理和决策提供数据支撑。整体架构呈现出分层、模块化、集约化的特点&#xff0c;并强调数据安全和标准规范。 智…

小迪安全23-php后台模块

cookie技术 cookie就是身份验证表示&#xff0c;通过cookie好区分每个用户的个人数据和权限&#xff0c;第一次登陆之后正常的网站都会赋予一个cookie 写写一个后台界面&#xff0c;直接让ai去写就可以 然后自己需要的提交方式&#xff0c;和表单值自己修改即可 生成cookie的…

大语言模型中的 Token如何理解?

在大语言模型中&#xff0c;Token 是文本处理的基本单元&#xff0c;类似于“文字块”&#xff0c;模型通过将文本分割成Token来理解和生成内容。举一个形象一点的例子&#xff0c;可以理解为 AI 处理文字时的“最小积木块”。就像搭乐高时&#xff0c;每块积木是基础单位一样&…

055 SpringCache

文章目录 缓存一致性Spring Cachepom.xmlapplication.ymlCubemallProductApplication.javaSpringCache改造三级分类MyCacheConfig.java缓存一致性 缓存一致性 锁 设置过期时间 读写锁 设置过期时间 Spring Cache 1.读模式 缓存穿透&#xff1a;查询一个null数据&#xff0c;…

机器学习数学基础:32.斯皮尔曼等级相关

斯皮尔曼等级相关教程 一、定义与原理 斯皮尔曼等级相关系数&#xff08;Spearman’s rank - correlation coefficient&#xff09;&#xff0c;常用 ρ \rho ρ表示&#xff0c;是一种非参数统计量&#xff0c;用于衡量两个变量的等级之间的关联程度。它基于变量的秩次&…

微信小程序-二维码绘制

wxml <view bindlongtap"saveQrcode"><!-- 二维码 --><view style"position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id"myQrcode" style"width: 200px; height: 200px;ba…