Validate Binary Search Tree

Problem

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

Given the root of a binary tree, determine if it is a valid binary search tree (BST).

A valid BST is defined as follows:

  • The left subtree of a node contains only nodes with keys strictly less than the node’s key.

  • The right subtree of a node contains only nodes with keys strictly greater than the node’s key.

  • Both the left and right subtrees must also be binary search trees.

Example 1:

image1

Input: root = [2,1,3]
Output: true

Example 2:

image2

Input: root = [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.

Constraints:

  • The number of nodes in the tree is in the range [1, 10:sup:`4`].

  • -2:sup:`31`<= Node.val <= 2:sup:`31`- 1

Pattern

Tree, Depth-First Search, Binary Search Tree, Binary Tree

Approaches

Code

from __future__ import annotations


class TreeNode:
    """Node in a binary tree."""

    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

    @classmethod
    def from_list(cls, vals: list[int | None]) -> TreeNode | None:
        if not vals:
            return None
        root = TreeNode(vals[0])
        queue = [root]
        i = 1
        while i < len(vals):
            node = queue.pop(0)
            if i < len(vals) and vals[i] is not None:
                node.left = TreeNode(vals[i])
                queue.append(node.left)
            i += 1
            if i < len(vals) and vals[i] is not None:
                node.right = TreeNode(vals[i])
                queue.append(node.right)
            i += 1
        return root

    def to_list(self) -> list:
        result = []
        queue = [self]
        while queue:
            node = queue.pop(0)
            if node:
                result.append(node.val)
                queue.append(node.left)
                queue.append(node.right)
            else:
                result.append(None)
        while result and result[-1] is None:
            result.pop()
        return result


def is_valid_bst(node, left, right):
    if node is None:
        return True

    if not (left < node.val < right):
        return False

    return is_valid_bst(node.left, left, node.val) and is_valid_bst(
        node.right, node.val, right
    )


def isValidBST(root: TreeNode | None) -> bool:
    return is_valid_bst(root, float("-inf"), float("inf"))

Test

>>> from validate_binary_search_tree__recursive import isValidBST, TreeNode
>>> isValidBST(TreeNode.from_list([2, 1, 3]))
True
>>> isValidBST(TreeNode.from_list([5, 1, 4, None, None, 3, 6]))
False
class validate_binary_search_tree__recursive.TreeNode(val=0, left=None, right=None)

Bases: object

Node in a binary tree.

classmethod from_list(vals: list[int | None]) TreeNode | None
to_list() list
validate_binary_search_tree__recursive.is_valid_bst(node, left, right)
validate_binary_search_tree__recursive.isValidBST(root: TreeNode | None) bool