Description
Given the root of a binary tree, determine if it is a valid binary search tree (BST).
A valid BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
Idea
本题需要我们判断一个二叉树是否为valid的binary search tree。BST的三个条件:
- 所有左子树节点均比根节点小
- 所有右子树节点均比根节点大
- 左右子树都是BST
可以先判断左右子树是否为BST,并判断是否左右子树的值均小于/大于根节点的值。
写code时需要注意逻辑, 并不能只判断左右子节点是否符合 < 根节点or > 根节点的要求,需要判断的是所有左子树的节点以及所有右子树的节点。
所有有两个思路:
- 分别判断左右子树 + 左边最大点和右边最小点是否符合要求
- 把当前根节点的值作为左子树的upper boundry, 右子树的lower boundry,并recursive地判断是否每一个子树的点都在boundry内。
Code
code 1
分别判断左右子树 + 左边最大点和右边最小点是否符合要求
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
is_valid, _max, _min = self.bst_val(root)
return is_valid
def bst_val(self, root):
'''
return的顺序为:is_valid, Max, Min
因为对于每一个子树我们要取其最大最小值, 所以当node为空时, Max= -inf, Min = inf
这样当存在另一个子树时,空子树的值会被覆盖
'''
if not root:
return True, -float('inf'), float('inf')
# 分别对于左右子树 return其 is_valid,max, min
left, max_left, min_left = self.bst_val(root.left)
right, max_right, min_right = self.bst_val(root.right)
max_val = max(max_left, max_right, root.val)
min_val = min(min_left, min_right, root.val)
# 当左子树有比root大的值或右子树有比root小的值时 return False
if max_left >= root.val or min_right <= root.val:
return False, max_val, min_val
# 当left == True and right == True时才能return True
return left and right, max_val, min_val
code 2
把当前根节点的值作为左子树的upper boundry, 右子树的lower boundry,并recursive地判断是否每一个子树的点都在boundry内
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
return self.dfs(root)
'''
对于根节点,initialize Min和Max的初始值为 - inf和 inf
'''
def dfs(self, root, Min = -float('inf'), Max = float('inf')):
# 当节点为空时, return True
if not root:
return True
# 当节点的值超出boundary时, return False
if root.val <= Min or root.val >= Max:
return False
# 该节点值在界内 再分别去看其左右子树是否符合要求
# 左子树的max value 被更新为当前root的值
# 右子树的min value 被更新为当前root的值
# 每一层的boundary都时由其根节点的值决定,所以可以层层递进地去判断是否每一层都符合BST的定义
return self.dfs(root.left, Min, root.val) and self.dfs(root.right, root.val, Max)
Notes
需要注意的点是:不仅需要判断左右子节点的值是否与root的值符合对应的大小关系,同时应满足左右子树的左右节点均满足对应的大小关系。