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

news/2025/2/25 6:37:27

题目:

给定二叉树的根节点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 = x
        self.left = None
        self.right = None

class Solution(object):
    def isValidBST(self, root):
        def helper(node, lower=float('-inf'), upper=float('inf')):
            # 如果节点为空,说明已经遍历到叶子节点或空树,返回 True
            if not node:
                return True

            val = node.val

            # 当前节点的值必须大于 lower 且小于 upper
            if val <= lower or val >= upper:
                return False

            # 递归检查右子树,将当前节点的值作为新的 lower
            if not helper(node.right, val, upper):
                return False

            # 递归检查左子树,将当前节点的值作为新的 upper
            if not helper(node.left, lower, val):
                return False

            return True

        return 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.left
            root=stack.pop()  #从栈中弹出一个节点
#之前压入的是当前节点和所有左子树节点,所以栈顶的节点是当前树的最左节点
            if root.val<=inorder:
                return False
            inorder=root.val #更新 inorder 为当前节点的值
            root=root.right #将当前节点的右子树作为下一个要处理的节点
        return True

        

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

空间复杂度:O(n)

源自扣官方题解
 


http://www.niftyadmin.cn/n/5865101.html

相关文章

【Linux】初识进程概念与 fork 函数的应用

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具Linux下进度条冯诺依曼体系与计算机系统架构 进程是操作系统中资源分配和调度的核心单位&#…

Junit+Mock

base project <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.11</version><relativePath/></parent><dependencies><!--添加mysql依…

微信小程序调用火山方舟(字节跳动火山引擎)中的DeepSeek大模型

一、注册火山引擎账号&#xff0c;创建API Key和model&#xff08;接入点ID&#xff09; 1.注册并登陆火山引擎账号&#xff0c;网址为&#xff1a;https://console.volcengine.com/ 2.根据登陆后的页面提示进行实名认证&#xff0c;实名认证后才能创建API Keyt和创建接入点。…

码率和采样率

“视频叫码率&#xff0c;音频叫采样率”这两者的命名来自于它们在处理过程中所关注的不同方面和技术原理&#xff0c;具体的解释如下&#xff1a; 1. 视频&#xff1a;码率 (Bitrate) 视频的码率指的是在视频编码过程中&#xff0c;每秒钟传输的数据量&#xff0c;通…

Oracle 数据泵迁移步骤规范

1、调研模块 1.1、确认迁移用户 以全库迁移为标准&#xff0c;也可直接通过需求方获取需要迁移的用户 1&#xff09;确认数据库中所有用户及其创建时间 alter session set nls_date_formatyyyy-mm-dd-hh24:mi:ss; select username,created from dba_users order by 2; 2&a…

docker compose安装redis

一、安装准备 在docker hub查看redis镜像版本。查看地址如下&#xff1a; Docker[这里是图片001]https://hub-stage.docker.com/_/redis/tags 二、拉取docker镜像 我这里用redis:6.2.14版本&#xff0c;先拉取镜像。命令如下&#xff1a; docker pull redis:6.2.14查看刚刚…

山东大学软件学院nosql实验四

实验题目&#xff1a; 使用Java做简单数据插入 实验内容 用API方式&#xff0c;做数据插入。 使用Java语言实现数据插入界面&#xff0c;为实验一建立的学生、教师、课程表插入数据&#xff0c;可以在前端界面中录入数据之后保存&#xff0c;也可以导入Excel中的数据。 实…

LeetCode 热题100 2. 两数相加

LeetCode 热题100 | 2. 两数相加 大家好&#xff0c;今天我们来解决一道经典的算法题——两数相加。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求我们将两个非空的链表表示的整数相加&#xff0c;并以相同形式返回一个表示和的链表。下面我将详细讲解解题思路&#…