LeetCode: 98.验证二叉搜索树

题目

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

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

  • 就是看一颗是是否满足二叉搜索树。

思路

  • 剑指里面有一道是判断一个序列是否是某二叉搜索树的中续遍历。一种简单的思路就是先中续遍历一遍,然后用剑指的办法判断。

  • 但经验告诉我,如果该树是二叉搜索树,我们需要走完所有的节点才能确定。但一旦某个节点不满足二叉搜索子树,我们是直接能得出整棵树都不是二叉搜索树。也就是提前阻断法,对于不是二叉搜索树的情况下,不必走完所有节点。比第一种办法的效率更加高。

  • 具体做法是。采用后续遍历,在递归中,判断该节点为根节点的子树是否是二叉搜索树。如果是,则返回True,该子树的最大值,该子树的最小值

  • 如何判断子树是否是二叉搜索树?如果对左子树遍历得到的flag为True,且当前节点值大于等于(不允许有重复节点)左子树的最大值,则左分支没问题;同理判断右分支。

  • 最后结合当前节点的值,重新计算最小值和最大值

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def walk(p):
            if not p:
                return True, -float('inf'), float('inf')
            val = p.val
            left, max_val_1, min_val_1 = walk(p.left)
            if not left or val <= max_val_1:  # 小于等于,等于不能缺少
                return False, 0, 0
            
            right, max_val_2, min_val_2 = walk(p.right)

            if not right or val >=min_val_2:
                return False, 0, 0
            max_val = max(val, max_val_1, max_val_2)
            min_val = min(val, min_val_1, min_val_2)
            return True, max_val, min_val
        flag, _, _ = walk(root)
        return flag        

其他方法

原来先序遍历和中序遍历都能提前阻断。
自己看了题解,写了一种中序遍历的思路,就是用path记录中序遍历的结果,当前节点和之前的节点比较大小。

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        path = []
        def walk(p):
            nonlocal path
            if not p:
                return True
            flag = walk(p.left)
            if not flag:
                return False
            if len(path) == 0:
                path.append(p.val)
            else:
                if path[-1] < p.val:
                    path.append(p.val)
                else:
                    return False
            flag = walk(p.right)
            return flag
        flag = walk(root)
        return flag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值