赞
踩
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
①节点的左子树只包含 小于 当前节点的数。
②节点的右子树只包含 大于 当前节点的数。
③所有左子树和右子树自身必须也是二叉搜索树。
输入:root = [2,1,3]
输出:true
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在[1, 10^4] 内
-2^31 <= Node.val <= 2^31 - 1
代码如下:
# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right import math class Solution: def isValidBST(self, root: Optional[TreeNode]) -> bool: # 定义无穷大与无穷小 Minimum = -math.pow(2,31) - 1 Maximum = math.pow(2,31) result = [True] def judgement(root,min,max): # 如果当前的根节点值在区间范围内则继续判断其左、右子树,并更新范围 if min < root.val and root.val < max: if root.left: # 当前节点存在左子树,则缩小上限为当前节点值,下限不变 judgement(root.left,min,root.val) if root.right: # 当前节点存右子树,则缩小下限为当前节点值,上限不变 judgement(root.right,root.val,max) else: # 如果当前节点值不在范围内,则结束当前进程,并认定该树不为二叉搜索树 result[0] = False return if root.left == None and root.right == None: #左右子树都为空时 return result[0] if root.left and root.right == None: #左子树不为空,右子树为空 judgement(root.left,Minimum,root.val) if root.left == None and root.right: #左子树为空,右子树不为空 judgement(root.right,root.val,Maximum) if root.left and root.right: # 左右子树都不为空 judgement(root.left,Minimum,root.val) judgement(root.right,root.val,Maximum) return result[0]
本题主要考察二叉搜索树的定义,需要对二叉搜索树的性质有一定理解,关于二叉搜索树的性质题目要求中已经给出,本题解不再赘述,下面来说一下本题的解题思路,以具体的二叉树为例:
我们想要判断这个数是否是二叉搜索树,则需要判断每一个节点是否满足条件,我们可以通过先看一下二叉树各个位置上的范围:
到这里就能很直观的看出来,每一个节点对应的位置的范围,如果该结点的值在这一范围内,则满足二叉搜索树的条件,反之则不满足。
如何判断当前节点的值所处范围是多少,很明显,通过示例图所示,分为两种情况:
①如果当前节点是上一个节点的左节点(即当前节点位于其父节点的左子树中),则其范围是:
[父节点范围的下限,父节点的值]
②如果当前节点是上一个节点的右节点(即当前节点位于其父节点的右子树中),则其范围是:
[父节点的值,父节点范围的上限]
我们只需要遍历二叉树每一个节点,每次更新当前节点对应的范围,然后判断当前节点的值是否位于该范围,就可以知道其是否满足二叉搜索树条件。
需要注意的是:
①题目要求中所提出,任意结点的值的范围是[-231,231-1],我们则需要设置一个超出这个范围的值作为-∞和+∞(本题以-231-1作为负无穷大;以231作为正无穷大)。
②所有的区间范围都应该是开区间,因为二叉搜索树中不应该存在重复的数值。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。