Validate if Tree is BST in DSA Python - Time & Space Complexity
We want to know how long it takes to check if a tree follows the rules of a Binary Search Tree (BST).
How does the time needed grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def is_bst(node, low=float('-inf'), high=float('inf')):
if not node:
return True
if not (low < node.val < high):
return False
return is_bst(node.left, low, node.val) and is_bst(node.right, node.val, high)
This code checks if a binary tree is a BST by making sure every node's value fits between allowed limits.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls visiting each node once.
- How many times: Once per node in the tree.
As the tree grows, the function visits every node exactly one time.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The number of operations grows directly with the number of nodes.
Time Complexity: O(n)
This means the time to check the tree grows in a straight line with the number of nodes.
[X] Wrong: "The function only checks some nodes, so it runs faster than O(n)."
[OK] Correct: The function must visit every node to be sure the tree is a BST, so it always checks all nodes.
Understanding this helps you explain how to verify tree properties efficiently, a common skill in coding interviews.
"What if we used an in-order traversal to check the BST property instead? How would the time complexity change?"
Practice
Solution
Step 1: Understand BST property
A BST requires that for each node, all values in the left subtree are smaller and all values in the right subtree are larger.Step 2: Compare options with definition
Every node's left subtree contains values less than the node, and right subtree contains values greater. matches this property exactly, while others describe different tree properties.Final Answer:
Every node's left subtree contains values less than the node, and right subtree contains values greater. -> Option DQuick Check:
BST property = Every node's left subtree contains values less than the node, and right subtree contains values greater. [OK]
- Confusing BST with balanced tree
- Thinking all nodes must have two children
- Assuming all values are equal
Solution
Step 1: Identify typical BST validation parameters
To validate BST, we usually pass the node and the allowed min and max value range to check subtree values.Step 2: Match function signatures
def validateBST(root, min_val, max_val): includes root, min_val, and max_val parameters, which is the standard approach for BST validation.Final Answer:
def validateBST(root, min_val, max_val): -> Option BQuick Check:
Function with min and max parameters = def validateBST(root, min_val, max_val): [OK]
- Using no parameters or wrong parameters
- Missing min and max value checks
- Incorrect function naming causing confusion
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def is_bst(node, min_val=float('-inf'), max_val=float('inf')):
if not node:
return True
if not (min_val < node.val < max_val):
return False
return (is_bst(node.left, min_val, node.val) and
is_bst(node.right, node.val, max_val))
root = Node(10)
root.left = Node(5)
root.right = Node(15)
root.left.left = Node(1)
root.left.right = Node(12)
print(is_bst(root))Solution
Step 1: Trace the tree structure and BST property
The node with value 12 is in the left subtree of 10 but greater than 10, violating BST rules.Step 2: Check the is_bst function logic
The function returns False because 12 is not less than 10 (max_val for left subtree), so the condition fails.Final Answer:
False -> Option CQuick Check:
Left subtree value > root = False [OK]
- Ignoring subtree value ranges
- Assuming all left children are smaller without checking ancestors
- Confusing node values with their immediate parent only
def is_bst(node, min_val=None, max_val=None):
if node is None:
return True
if min_val and node.val <= min_val:
return False
if max_val and node.val >= max_val:
return False
return is_bst(node.left, min_val, node.val) and is_bst(node.right, node.val, max_val)Solution
Step 1: Analyze condition checks for min_val and max_val
Using 'if min_val' fails when min_val is 0 or negative because 0 is False in Python.Step 2: Identify correct way to check None
We should check 'if min_val is not None' to correctly handle 0 or negative values.Final Answer:
Using 'if min_val' causes incorrect checks when min_val is 0 or negative. -> Option AQuick Check:
Check None explicitly, not truthiness [OK]
- Using truthy checks for numeric bounds
- Ignoring zero or negative values in conditions
- Misordering recursive parameters
def is_bst_with_duplicates(node, min_val=float('-inf'), max_val=float('inf')):
if not node:
return True
# Fill condition here
return (is_bst_with_duplicates(node.left, min_val, node.val) and
is_bst_with_duplicates(node.right, node.val, max_val))Solution
Step 1: Understand duplicate placement rule
Duplicates allowed only on right means left subtree values must be strictly less than node.val, right subtree values can be equal or greater.Step 2: Adjust inequality conditions accordingly
Left subtree uses min_val <= node.val < max_val, so node.val can be equal to min_val but less than max_val. For right subtree, node.val can be equal to min_val.Final Answer:
Change condition to: if not (min_val <= node.val < max_val): return False -> Option AQuick Check:
Duplicates on right: allow equality on right side [OK]
- Allowing duplicates on left subtree
- Using strict inequalities on both sides
- Not adjusting min_val and max_val checks
Ready to prove it?
Pass the test and this pattern moves unknown
