98. 验证二叉搜索树

98. 验证二叉搜索树

题意

判断二叉树是否是BST,要求不能出现等于的情况,也就是左子树必须比结点小,右子树必须比结点大。

解题思路

如果对于BST的理解没有那么到位的话,可能就会写出下面的代码:

class Solution:
   def isValidBST(self, root):
       """
      :type root: TreeNode
      :rtype: bool
      """
       if not root:
           return True

       if root.left and root.left.val >= root.val:
           return False

       if root.right and root.right.val <= root.val:
           return False

       return self.isValidBST(root.left) and self.isValidBST(root.right)

这么会存在一个问题,上面仅仅是判断了当前结点和左右子树的值,则没有考虑到祖父结点和父亲结点和子结点的值的比较,比如:

所以应该是将上一个结点和当前访问的结点进行比较;

正确的思路如下:

  • 利用中序遍历的思想,将其转为数组,判断是否有序即可;

  • 同样利用中序遍历的思想,维护一个变量来记录当前结点的前一个访问的结点(数组的最后一个值作为最新访问的值)保证当前结点比前一个访问的结点要大即可;

  • 控制区间的思想,保证当前树的值的范围在对应的区间即可,如下:

实现

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
   def isValidBST(self, root):
       """
      :type root: TreeNode
      :rtype: bool
      """
       def dfs(node):
           if not node:
               return
           
           # 加入到数组中后面利用排序进行比较
           dfs(node.left)
           nums.append(node.val)
           dfs(node.right)
           
       if not root:
           return True
       
       nums = []
       dfs(root)
       return len(set(nums)) == len(nums) and sorted(nums) == nums
   
def isValidBST(self, root):
       """
      :type root: TreeNode
      :rtype: bool
      """
       def dfs(node, path):
           if not node:
               return True
           
           if not dfs(node.left, path):
               return False
           # 和前一个访问的结点的值进行比较,保证当前结点值比前一个结点的值要大;
           # 利用数组来维护上次访问的值
           if path and node.val <= path[-1]:
               return False
           path.append(node.val)
           
           return dfs(node.right, path)
           
       if not root:
           return True
       nums = []
       return dfs(root, nums)
     
last_visit_node = None
   def isValidBST(self, root):
       """
      :type root: TreeNode
      :rtype: bool
      """

       def dfs(node):
           if not node:
               return True

           if not dfs(node.left):
               return False

           # 和前一个访问的结点的值进行比较,保证当前结点值比前一个结点的值要大;
           # 利用类变量来维护上次访问的值
           if self.last_visit_node and node.val <= self.last_visit_node.val:
               return False
           self.last_visit_node = node
           return dfs(node.right)

       if not root:
           return True
       return dfs(root)
   
def isValidBST(self, root):
       """
      :type root: TreeNode
      :rtype: bool
      """
       def helper(node, lo, hi):
           if node == None:
               return True
           # 如果访问左结点,则设置最大值为当前结点的值,如果访问右结点,则设置最小值为当前结点的值;
           return lo < node.val < hi and \
                  helper(node.left, lo, node.val) and \
                  helper(node.right, node.val, hi)
       return helper(root, float('-Inf'), float('Inf'))
posted @ 2017-09-03 10:10  banananana  阅读(177)  评论(0编辑  收藏  举报