98. 验证二叉搜索树

递归的中序遍历,动态的进行比较

class lei():
    def __init__(self):
        self.prevalue=-float('inf')  #负无穷
    def fun1(self,root):#递归形式的中序遍历
        if root==None:  #基本结束条件
            return True  #说明是正常结束
        bool1=self.fun1(root.left)  #看左子树是否为正常的
        if not bool1:
            return False

        if self.prevalue<root.val:
            self.prevalue=root.val
        else:
            return False



        return self.fun1(root.right)

不动态进行比较,全部入数组,在递归结束后统一进行比较,是非常稳妥的方法

class Solution:
    def isValidBST(self, root) -> bool:
        ls=[]
        def fun2(root,ls):
            if root==None:
                return
            fun2(root.left,ls)
            ls.append(root.val)
            fun2(root.right,ls)
        fun2(root,ls)
        for i in range(len(ls)-1):
            if ls[i]>=ls[i+1]:
                return False
        return True

非递归代码,对于我现在而言比较简单,相对递归代码动态比较也更为容易

def fun3(root):
    pre=-float('inf')   #上一个节点的大小,对于中序遍历应该是一样的
    stack=[]
    while stack or root: #只要有一个不为空就可以进来
        while root:
            stack.append(root)  #当前节点入栈
            root=root.left
        root=stack.pop()
        if pre>=root.val:
            return False
        else:
            pre=root.val
        root=root.right
    return True

树形动态规划
动态规划,在具有大量重复计算,或后序步骤可以使用前面结果,并且随着代码的运行前面的,结果不会改变的时候进行使用的一种方法
那么这个题目
如果我知道了一个节点的两个子树的相关信息,如是否为二叉搜索树,对应的最大值,最小值那么相应的结果就可以出来了

def main4(root):
    return fun4(root)[0]

def fun4(x):
    '''
        分治思想
        如果我要搞一个搜索二叉树,肯定是这个样子
        1.对于任意节点,我的左子树要是搜索二叉树
        2.对于任意节点,我的右子树要是搜索二叉树
        3.对于任意节点,我的左子树的所有值要小于该节点的值(即左子树最大值小于该节点的值)
        4.对于任意节点,我的右子树的所有值要大于该节点的值(即右子树最小值大于该节点的值)
    :param x:
    :return:
    '''
    if x==None:
        return None  #是搜索二叉树,要单独讨论叶节点的问题
    dui1=fun4(x.left)    #是否为二叉搜索树,最小值,最大值
    dui2=fun4(x.right)

    if dui1 and dui2:#都不空
        fhz=dui1[0] and dui2[0] and dui1[2]<x.val and dui2[1]>x.val
        z=dui1[1]
        y=dui2[2]
        return fhz,z,y
    elif dui1 and (not dui2): #只有左子树,没有右子树
        fhz=dui1[0] and dui1[2]<x.val
        z=dui1[1]
        y=x.val
        return fhz,z,y
    elif (not dui1) and dui2:
        fhz=dui2[0] and dui2[1]>x.val
        z=x.val
        y=dui2[2]
        return fhz,z,y
    else:#都没有
        return True,x.val,x.val

树形动态规划

'''
    我上面代码虽然通过了,但在这里写的应该有些问题
        fhz=dui1[0] and dui2[0] and dui1[2]<x.val and dui2[1]>x.val
        z=dui1[1]
        y=dui2[2]
        return fhz,z,y
        如果这样写,我返回的z和y不一定是该树的最小,最大值
        但是想想代码为什么可以通过,因为我的<<"错误">>是不断累积的
        如果在有一次的递归过程中,我得到了fhz为False,假设他为第一次,那么一定是在这一次之后(包括这一次)返回的最大,最小有问题
        而在后面的过程中,因为False起着关键性的作用,所以最大,最小值就不在这么重要了
        
        即:如果始终为True那么最大最小始终是对的
        如果变为False,则不需要最大最小值
'''
def main5(root):
    return fun4(root)[0]

def fun5(x):
    '''
        分治思想
        如果我要搞一个搜索二叉树,肯定是这个样子
        1.对于任意节点,我的左子树要是搜索二叉树
        2.对于任意节点,我的右子树要是搜索二叉树
        3.对于任意节点,我的左子树的所有值要小于该节点的值(即左子树最大值小于该节点的值)
        4.对于任意节点,我的右子树的所有值要大于该节点的值(即右子树最小值大于该节点的值)
    :param x:
    :return:
    '''
    if x==None:
        return None  #是搜索二叉树,要单独讨论叶节点的问题
    dui1=fun5(x.left)    #是否为二叉搜索树,最小值,最大值
    dui2=fun5(x.right)

    if dui1 and dui2:#都不空
        fhz=dui1[0] and dui2[0] and dui1[2]<x.val and dui2[1]>x.val
        z=min(dui1[1],x.val)
        y=max(dui2[2],x.val)
        return fhz,z,y
    elif dui1 and (not dui2): #只有左子树,没有右子树
        fhz=dui1[0] and dui1[2]<x.val
        z=min(dui1[1],x.val)
        y=x.val
        return fhz,z,y
    elif (not dui1) and dui2:
        fhz=dui2[0] and dui2[1]>x.val
        z=x.val
        y=max(dui2[2],dui2[2])
        return fhz,z,y
    else:#都没有
        return True,x.val,x.val
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值