Trees and Binary Search Trees: Taxonomy, Invariant, and Traversal/Search
SIG (Susquehanna)Software Engineer · OnsiteLast updated
Tests understanding of binary tree taxonomy, global BST invariants versus local parent-child checks, and efficient tree search under range constraints.
Problem Statement
A Binary Search Tree (BST) is defined by a strict global invariant: for any given node with key k, every node in its left subtree must have a key strictly less than k, and every node in its right subtree must have a key strictly greater than k.
You are asked to implement two functions that operate on binary trees:
validate_bst(root: Optional[TreeNode]) -> bool: ReturnsTrueif the tree satisfies the strict BST invariant at every node, andFalseotherwise.find_closest_in_range(root: Optional[TreeNode], target: int, low: int, high: int) -> Optional[int]: Given the root of a valid BST, returns the key in the inclusive range[low, high]that is closest totarget(i.e., minimizesabs(key - target)). If multiple keys are equidistant fromtarget, return the smaller key. If no keys in the tree lie within[low, high], returnNone.
Your solution for find_closest_in_range must leverage the BST ordering property to prune subtrees that cannot contain valid candidate keys.
Interface
class TreeNode:
def __init__(self, val: int = 0, left: 'TreeNode' = None, right: 'TreeNode' = None):
self.val = val
self.left = left
self.right = right
def validate_bst(root: Optional[TreeNode]) -> bool:
pass
def find_closest_in_range(root: Optional[TreeNode], target: int, low: int, high: int) -> Optional[int]:
pass
Input & Output Format
validate_bsttakes the root of a binary tree and returns a boolean.find_closest_in_rangetakes the root of a verified BST and three integers (target,low,high), returning an integer orNone.
Constraints
- The number of nodes
nin the tree is in the range[0, 10^5]. -10^9 <= TreeNode.val, target, low, highFalse`- Explanation: The node with value
6is in the right subtree of10, which violates the invariant6 > 10.
Example 2
Input Tree:
20
/ \
10 30
/ \ \
5 15 35
validate_bst(root)->Truefind_closest_in_range(root, target=12, low=6, high=18)->10- Explanation: The nodes within
[6, 18]are10and15. Distances to12areabs(10 - 12) = 2andabs(15 - 12) = 3. The closest is10.
Edge Cases
- An empty tree (
root is None):validate_bstshould returnTrue;find_closest_in_rangeshould returnNone. - No nodes fall within the range
[low, high].
Hints
Hint 1
A common bug in BST validation is only checking that left.val < root.val < right.val; ensure you pass min and max boundaries down during traversal.
Hint 2
For the range search, if a node's value is strictly less than low, its entire left subtree is also strictly less than low and can be skipped.
Hint 3
Keep track of the closest valid candidate seen so far, and greedily explore the subtree that is in the direction of target whenever possible.
Follow-up questions
- How does the time complexity of both operations vary between a self-balancing BST (e.g., AVL or Red-Black tree) and a degenerate linked-list tree?
- How would your validation logic change if duplicate values were permitted in the left subtree?
- Can you perform the BST validation iteratively in O(1) auxiliary space without modifying the tree structure permanently (e.g., using Morris traversal)?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.