给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
 - 节点的右子树只包含 大于 当前节点的数。
 
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:

输入:root = [2,1,3]
 输出:true
 示例 2:

输入:root = [5,1,4,null,null,3,6]
 输出:false
 解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在 
     
      
       
       
         [ 
        
       
         1 
        
       
         , 
        
       
         1 
        
        
        
          0 
         
        
          4 
         
        
       
         ] 
        
       
      
        [1, 10^4] 
       
      
    [1,104] 内
  
     
      
       
       
         − 
        
        
        
          2 
         
        
          31 
         
        
       
         < 
        
       
         = 
        
       
         N 
        
       
         o 
        
       
         d 
        
       
         e 
        
       
         . 
        
       
         v 
        
       
         a 
        
       
         l 
        
       
         < 
        
       
         = 
        
        
        
          2 
         
        
          31 
         
        
       
         − 
        
       
         1 
        
       
      
        -2^{31} <= Node.val <= 2^{31} - 1 
       
      
    −231<=Node.val<=231−1
思想来自官方解说。这个问题比较容易想到递归,但是递归过程中需要注意一个问题,不能只检查当前节点跟左右两个子节点的大小关系,因为BST要求当前节点的左子树的节点都要小于当前节点,这种可能出现不符合BST规则的地方主要存在于:遍历左子树的右子树时,需要右子树大于父节点同时小于爷爷节点;遍历右子树的左子树时,需要左子树小于父节点同时大于爷爷节点。
递归遍历是深度优先遍历,是自上而下的遍历,遇到不符合的节点会提前返回,而不往下继续遍历。
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def helper(node, lower=None, upper=None) -> bool:
            if not node:
                return True
            val = node.val
            if (lower is not None and val <= lower) or (upper is not None and val >= upper):
                return False
            #左右子树的遍历顺序没有要求
            if not helper(node.right, val, upper):
                return False
            if not helper(node.left, lower, val):
                return False
            return True
        return helper(root)
                
















