📌  相关文章
📜  国际空间研究组织 | ISRO CS 2017 – 5 月 |问题 41(1)

📅  最后修改于: 2023-12-03 14:50:48.082000             🧑  作者: Mango

国际空间研究组织 | ISRO CS 2017 – 5 月 |问题 41

题目描述

给定一个二叉树的根节点,编写一个函数来检查它是否是BST(二叉搜索树)。 如果一个二叉树的左子树中的每个节点的值小于其根节点的值,而其右子树中的每个节点的值都大于其根节点的值,则该二叉树被称为BST。

函数签名
def is_bst(root: TreeNode) -> bool:
    pass
输入
  • root:二叉树的根节点,类型为TreeNode
输出
  • 类型为bool的值,表示二叉树是否为BST
示例
# 示例1
# 输入
#      2
#     / \
#    1   3
# 输出:True

# 示例2
# 输入
#      5
#     / \
#    1   4
#       / \
#      3   6
# 输出:False
tree1 = TreeNode(2)
tree1.left = TreeNode(1)
tree1.right = TreeNode(3)
assert is_bst(tree1) is True

tree2 = TreeNode(5)
tree2.left = TreeNode(1)
tree2.right = TreeNode(4)
tree2.right.left = TreeNode(3)
tree2.right.right = TreeNode(6)
assert is_bst(tree2) is False
解题思路

题目要求判断二叉树是否是BST,所以需要找到BST的特性。BST是具有如下性质的二叉树:

  1. 对于任意节点n,n左子树中的所有节点的值均小于n的值
  2. 对于任意节点n,n右子树中的所有节点的值均大于n的值
  3. n的左右子树也分别是BST

所以我们可以定义一个递归函数来判断当前节点是否符合以上三个特性即可。其中还需要考虑一个问题,由于二叉树的左子树中的节点要比根节点小,而右子树中的节点要比根节点大,所以我们需要在递归函数中同时传入该节点为根节点的子树范围的最大值和最小值。

对于每个节点n而言,它需要满足如下条件:

  1. 当前节点的值要在父亲节点的子树范围内
  2. 当前节点左子树内的所有节点的值要在n的值的左边
  3. 当前节点右子树内的所有节点的值要在n的值的右边
参考代码
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


def is_bst(root: TreeNode) -> bool:
    def helper(node: TreeNode, lower=float('-inf'), upper=float('inf')) -> bool:
        if node is None:
            return True

        if node.val <= lower or node.val >= upper:
            return False

        return helper(node.left, lower, node.val) and helper(node.right, node.val, upper)

    return helper(root)

使用辅助函数来递归判断二叉树是否符合BST的特性。在递归函数中,我们传入三个参数:

  1. node:表示当前节点
  2. lower:表示当前节点的值需要在此范围内,初始值为负无穷
  3. upper:表示当前节点的值需要在此范围内,初始值为正无穷

当递归到某个节点时,如果它的值不在该节点所处的范围内,说明它不符合BST的特性,返回False;否则,继续递归它的左右子树,传入的范围限定为[lower, node.val][node.val, upper],如果左右子树均符合BST的特性,则返回True,否则返回False。