98验证二叉搜索树

题目: 给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:1节点的左子树只包含小于当前节点的数 2 节点的右子树只包含大于当前节点的数 3 所有左子树和右子树自身必须也是二叉搜索树

来源: https://leetcode-cn.com/problems/validate-binary-search-tree/

法一: 官网递归方法

思路: 解题前先判断题目与二叉树的遍历方式有无关系,如果有关要先识别该用哪种遍历方法求解.必须要先画一个二叉树的图,对每个节点的范围标定后进行观察可发现,每个节点往下走的时候,如果是向右走,则该节点的值作为右子树区间的左端点.如果向左走,则该节点的值作为左子树区间的右端点.观察出规律来,还要用递归实现.

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 递归解法,
# 这个解法的关键是要画出图来,通过观察画出的树图可以看出,每个节点的都有一个范围,该节点下面的左子树和右子树的范围即为用
# 该节点的值分割节点所在的区间,要观察出这一点即可用迭代方法解决本题
class Solution:
    def isValidBST(self, root):
        def helper(node, lower=float('-inf'), upper=float('inf')):
            # 如果节点为空,则返回True
            if not node:
                return True
            val = node.val
            # 根节点的范围是-inf到inf,先用这两个来确定范围,也为了方便后续的传参
            # 如果不在这个范围内,则返回False
            if val <= lower or 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)
if __name__ == '__main__':
    duixiang = Solution()
    root = TreeNode(8)
    a = TreeNode(4)
    b = TreeNode(9)
    root.left = a
    root.right = b
    al = TreeNode(3)
    ar = TreeNode(6)
    a.left = al
    a.right = ar
    arl = TreeNode(5)
    arr = TreeNode(7)
    ar.left = arl
    ar.right = arr
    a = duixiang.isValidBST(root)
    print(a)
View Code

法二: 利用了二叉树中序遍历最经典的迭代方法.

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 这个解法利用的是二叉树中序遍历的迭代算法
class Solution:
    def isValidBST(self, root):
        stack, inorder = [], float('-inf')
        while stack or root:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            # 如果这里有res.append(root.val),则res中最后存储的即为二叉树的中序遍历,
            # inorder是上一个数,root.val是下一个数,如果下一个大于上一个了,则不是二叉搜索树,返回False
            if root.val <= inorder:
                return False
            inorder = root.val
            root = root.right
        return True
if __name__ == '__main__':
    duixiang = Solution()
    root = TreeNode(8)
    a = TreeNode(4)
    b = TreeNode(9)
    root.left = a
    root.right = b
    al = TreeNode(3)
    ar = TreeNode(6)
    a.left = al
    a.right = ar
    arl = TreeNode(5)
    arr = TreeNode(7)
    ar.left = arl
    ar.right = arr
    a = duixiang.isValidBST(root)
    print(a)
View Code

法三: 自己参考官网解法后的代码

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 执行用时 :48 ms, 在所有 python3 提交中击败了95.99% 的用户
# 内存消耗 :15.3 MB, 在所有 python3 提交中击败了99.64%的用户
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        #
        res = [float('-inf')]
        stack = []
        stack.append((root, 1))
        while stack:
            x, sign = stack.pop()
            if x is None:
                continue
            # 这里用0标记被遍历过了,1表示没有遍历,如遍历过了则存储
            # 否则继续遍历,一直朝左找到底
            if sign:
                # 中序遍历
                stack.append((x.right, 1))
                stack.append((x, 0))
                stack.append((x.left, 1))
            else:
                # res中存储的是中序遍历
                res.append(x.val)
                # 如果不成立,说明不是二叉树搜索树,直接返回False
                if res[-1] - res[-2] > 0:
                    pass
                else:
                    return False
        return True
if __name__ == '__main__':
    duixiang = Solution()
    root = TreeNode(8)
    a = TreeNode(4)
    b = TreeNode(9)
    root.left = a
    root.right = b
    al = TreeNode(3)
    ar = TreeNode(6)
    a.left = al
    a.right = ar
    arl = TreeNode(5)
    arr = TreeNode(7)
    ar.left = arl
    ar.right = arr
    a = duixiang.isValidBST(root)
    print(a)
View Code

posted on 2019-12-05 19:17  吃我一枪  阅读(179)  评论(0编辑  收藏  举报

导航