Validate if Tree is BST in DSA Typescript - 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.
function isBST(node: TreeNode | null, min: number = -Infinity, max: number = Infinity): boolean {
if (node === null) return true;
if (node.val <= min || node.val >= max) return false;
return isBST(node.left, min, node.val) && isBST(node.right, node.val, max);
}
This code checks if a binary tree is a BST by making sure each node's value fits between allowed minimum and maximum 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 once to check its value.
| 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 whole tree follows BST rules, 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 has smaller values and right subtree has larger values matches the BST property exactly, while others describe different tree properties.Final Answer:
Every node's left subtree has smaller values and right subtree has larger values -> Option DQuick Check:
BST property = Every node's left subtree has smaller values and right subtree has larger values [OK]
- Confusing BST with balanced tree
- Thinking all nodes must have two children
- Assuming all values are equal
Solution
Step 1: Identify correct parameter and return types
The function should accept a tree node or null and return a boolean indicating if it is a BST.Step 2: Match options with correct signature
function isBST(root: TreeNode | null): boolean matches this: input is TreeNode or null, output is boolean. Others have wrong types or return types.Final Answer:
function isBST(root: TreeNode | null): boolean -> Option BQuick Check:
Correct signature = function isBST(root: TreeNode | null): boolean [OK]
- Using wrong parameter type like number
- Returning number instead of boolean
- Using void return type
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val: number, left: TreeNode | null = null, right: TreeNode | null = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function isBST(root: TreeNode | null, min: number = -Infinity, max: number = Infinity): boolean {
if (!root) return true;
if (root.val <= min || root.val >= max) return false;
return isBST(root.left, min, root.val) && isBST(root.right, root.val, max);
}
const tree = new TreeNode(10, new TreeNode(5), new TreeNode(15, new TreeNode(6), new TreeNode(20)));
console.log(isBST(tree));Solution
Step 1: Analyze the tree structure
The root is 10, left child 5 (valid), right child 15 with left child 6 and right child 20.Step 2: Check BST property on right subtree
Node 6 is in right subtree of 10 but less than 10, violating BST property. So function returns false.Final Answer:
false -> Option CQuick Check:
6 in right subtree < 10 = false [OK]
- Ignoring min/max constraints in recursion
- Assuming all subtrees are BST without checks
- Confusing node values in subtrees
function isBST(root: TreeNode | null): boolean {
if (!root) return true;
if (root.left && root.left.val > root.val) return false;
if (root.right && root.right.val < root.val) return false;
return isBST(root.left) && isBST(root.right);
}Solution
Step 1: Understand the function checks
The function only compares immediate children values with current node, not entire subtree ranges.Step 2: Explain why this is a bug
BST requires all nodes in left subtree < current node and all in right subtree > current node, not just direct children.Final Answer:
It does not check the entire subtree values against min/max limits -> Option AQuick Check:
Missing min/max range check = It does not check the entire subtree values against min/max limits [OK]
- Only comparing direct children values
- Ignoring recursive min/max constraints
- Assuming null nodes cause errors
root.val <= min in the validation function:
function isBST(root: TreeNode | null, min: number = -Infinity, max: number = Infinity): boolean {
if (!root) return true;
if (root.val <= min || root.val >= max) return false;
return isBST(root.left, min, root.val) && isBST(root.right, root.val, max);
}Solution
Step 1: Understand duplicates on right subtree rule
Duplicates allowed only on right means left subtree nodes must be strictly less than current node, right subtree nodes greater than or equal.Step 2: Adjust min/max comparisons accordingly
Replaceroot.val <= minwithroot.val < min. This fails only if strictly less than min (allows equal to min on right recursion), keepingroot.val >= maxfor strict upper bound.Final Answer:
Change toroot.val < minto allow duplicates on right -> Option AQuick Check:
Duplicates right subtree = Change toroot.val < min[OK]
- Allowing duplicates on left subtree
- Using <= on both sides
- Not changing min/max checks
Ready to prove it?
Pass the test and this pattern moves unknown
