Leetcode 98:验证二叉搜索树(最详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/82315830

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:
    2
   / \
  1   3
输出: true

示例 2:

输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4

解题思路

这个问题和之前的问题Leetcode 110:平衡二叉树(最详细的解法!!!)类似,但是这个问题有一个陷阱,我们参考之前的写法,很容易写出下面这种写法。

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)

上述写法,没有考虑这种情况

    10
   /  \
  5    15
      /  \
     6    20

这种写法的错误在于没有理清楚子问题的本质。节点左子树的所有节点都小于当前节点,而不是仅仅左根节点小于root,对于右子树同理。我们只要对上述写法稍加修改

class Solution:
    def _isValidBST(self, root, min_t=float('-inf'), max_t=float('inf')):
        if not root:
            return True

        if min_t < root.val < max_t and self._isValidBST(root.left, min_t, root.val) and self._isValidBST(root.right, root.val, max_t):
            return True

        return False

    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self._isValidBST(root)

这里我更加推荐下面的这种写法

class Solution:
    def _isValidBST(self, root, left=None, right=None):
        if not root:
            return True

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

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

        return self._isValidBST(root.left, left, root) and self._isValidBST(root.right, root, right)

    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self._isValidBST(root)

我们同样写出递归版本,我们这里要用到一个很重要的性质。

二分搜索树的中序遍历是一个有序数列

所以我们这里可以使用中序遍历的递归写法解决这个问题。

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

        pre = None
        stack = list()
        while root or stack:
            if root:
                stack.append(root)
                root = root.left
            else:
                root = stack.pop()
                if pre and root.val <= pre.val:
                        return False

                pre = root
                root = root.right

        return True

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/82315830