mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-02 17:31:08 +00:00
3e1cb70abf
* add algorithm to check binary search tree * add tests * add leetcode link * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix typehints * typehints fixes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix flake8 * fix typehint * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add TreeNode resolving * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * Update data_structures/binary_tree/is_bst.py Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> * Update data_structures/binary_tree/is_bst.py Co-authored-by: Christian Clauss <cclauss@me.com> * change func name * Update data_structures/binary_tree/is_bst.py Co-authored-by: Christian Clauss <cclauss@me.com> * review notes fixes. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix flake8 * fix flake 8 * fix doctest * Update data_structures/binary_tree/is_bst.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Caeden Perelli-Harris <caedenperelliharris@gmail.com> Co-authored-by: Christian Clauss <cclauss@me.com>
132 lines
3.8 KiB
Python
132 lines
3.8 KiB
Python
"""
|
|
Author : Alexander Pantyukhin
|
|
Date : November 2, 2022
|
|
|
|
Task:
|
|
Given the root of a binary tree, determine if it is a valid binary search
|
|
tree (BST).
|
|
|
|
A valid binary search tree is defined as follows:
|
|
|
|
- The left subtree of a node contains only nodes with keys less than the node's key.
|
|
- The right subtree of a node contains only nodes with keys greater than the node's key.
|
|
- Both the left and right subtrees must also be binary search trees.
|
|
|
|
Implementation notes:
|
|
Depth-first search approach.
|
|
|
|
leetcode: https://leetcode.com/problems/validate-binary-search-tree/
|
|
|
|
Let n is the number of nodes in tree
|
|
Runtime: O(n)
|
|
Space: O(1)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class TreeNode:
|
|
data: float
|
|
left: TreeNode | None = None
|
|
right: TreeNode | None = None
|
|
|
|
|
|
def is_binary_search_tree(root: TreeNode | None) -> bool:
|
|
"""
|
|
>>> is_binary_search_tree(TreeNode(data=2,
|
|
... left=TreeNode(data=1),
|
|
... right=TreeNode(data=3))
|
|
... )
|
|
True
|
|
|
|
>>> is_binary_search_tree(TreeNode(data=0,
|
|
... left=TreeNode(data=-11),
|
|
... right=TreeNode(data=3))
|
|
... )
|
|
True
|
|
|
|
>>> is_binary_search_tree(TreeNode(data=5,
|
|
... left=TreeNode(data=1),
|
|
... right=TreeNode(data=4, left=TreeNode(data=3)))
|
|
... )
|
|
False
|
|
|
|
>>> is_binary_search_tree(TreeNode(data='a',
|
|
... left=TreeNode(data=1),
|
|
... right=TreeNode(data=4, left=TreeNode(data=3)))
|
|
... )
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueError: Each node should be type of TreeNode and data should be float.
|
|
|
|
>>> is_binary_search_tree(TreeNode(data=2,
|
|
... left=TreeNode([]),
|
|
... right=TreeNode(data=4, left=TreeNode(data=3)))
|
|
... )
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueError: Each node should be type of TreeNode and data should be float.
|
|
"""
|
|
|
|
# Validation
|
|
def is_valid_tree(node: TreeNode | None) -> bool:
|
|
"""
|
|
>>> is_valid_tree(None)
|
|
True
|
|
>>> is_valid_tree('abc')
|
|
False
|
|
>>> is_valid_tree(TreeNode(data='not a float'))
|
|
False
|
|
>>> is_valid_tree(TreeNode(data=1, left=TreeNode('123')))
|
|
False
|
|
"""
|
|
if node is None:
|
|
return True
|
|
|
|
if not isinstance(node, TreeNode):
|
|
return False
|
|
|
|
try:
|
|
float(node.data)
|
|
except (TypeError, ValueError):
|
|
return False
|
|
|
|
return is_valid_tree(node.left) and is_valid_tree(node.right)
|
|
|
|
if not is_valid_tree(root):
|
|
raise ValueError(
|
|
"Each node should be type of TreeNode and data should be float."
|
|
)
|
|
|
|
def is_binary_search_tree_recursive_check(
|
|
node: TreeNode | None, left_bound: float, right_bound: float
|
|
) -> bool:
|
|
"""
|
|
>>> is_binary_search_tree_recursive_check(None)
|
|
True
|
|
>>> is_binary_search_tree_recursive_check(TreeNode(data=1), 10, 20)
|
|
False
|
|
"""
|
|
|
|
if node is None:
|
|
return True
|
|
|
|
return (
|
|
left_bound < node.data < right_bound
|
|
and is_binary_search_tree_recursive_check(node.left, left_bound, node.data)
|
|
and is_binary_search_tree_recursive_check(
|
|
node.right, node.data, right_bound
|
|
)
|
|
)
|
|
|
|
return is_binary_search_tree_recursive_check(root, -float("inf"), float("inf"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import doctest
|
|
|
|
doctest.testmod()
|