NeetCode #442LC-98MediumTreesBlind 75NC 150NC 250
← Back to All Problems#442 · #98 · Validate Binary Search Tree(验证二叉搜索树)
📌 Problem Statement & Constraints
Given the root of a binary tree, determine whether it is a valid binary search tree: every node's value must be strictly greater than all values in its left subtree and strictly less than all values in its right subtree. Constraints: the number of nodes is in
[1, 10^4], -2^31 <= Node.val <= 2^31 - 1.💡 Core Algorithmic Approaches
- Checking only that each node's value lies between its immediate children is insufficient -- a violation can occur several levels deep.
- Carry the allowed open interval
(lo, hi)down the recursion. - Going left tightens
hito the current value; going right tightenslo. - A node is valid when
lo < node.val < hi. The initial interval is(-infinity, +infinity).
💻 Benchmark Python3 Implementation
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def check(node: Optional[TreeNode], lo: float, hi: float) -> bool:
if not node:
return True
if not (lo < node.val < hi): # outside the allowed open interval
return False
return (check(node.left, lo, node.val)
and check(node.right, node.val, hi))
return check(root, float("-inf"), float("inf"))
# In-order variant: the traversal must be strictly increasing
class Solution2:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
prev = float("-inf")
def inorder(node: Optional[TreeNode]) -> bool:
nonlocal prev
if not node:
return True
if not inorder(node.left):
return False
if node.val <= prev: # not strictly increasing
return False
prev = node.val
return inorder(node.right)
return inorder(root)⚡ Complexity Deep Dive
⏱️ Time Complexity
O(n): every node is visited once.
💾 Space Complexity
O(h) for the recursion stack.
⚠️ Interview Pitfalls & Follow-ups
- Only comparing a node with its immediate children:
[10, 5, 15, null, null, 6, 20]passes that test but is invalid, because 6 is in the right subtree of 10. The interval approach catches it. - Using closed intervals
lo <= node.val <= hi: duplicate values are not allowed, so the bounds must be strict. - Initialising the interval with
float('-inf')/float('inf'): correct, and safe even for 32-bit extreme values. Using-231and231 - 1as bounds would break for a node with exactly those values. - Comparing with the previous node in a pre-order traversal: only the in-order traversal gives the sorted order.