Validate if Tree is BST in DSA C - Time & Space Complexity
We want to know how long it takes to check if a tree is a valid Binary Search Tree (BST).
The question is: how does the time needed grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
// Structure for tree node
struct Node {
int data;
struct Node* left;
struct Node* right;
};
// Helper function to validate BST
int isBSTUtil(struct Node* node, int min, int max) {
if (node == NULL) return 1;
if (node->data <= min || node->data >= max) return 0;
return isBSTUtil(node->left, min, node->data) &&
isBSTUtil(node->right, node->data, max);
}
// Main function to check BST
int isBST(struct Node* root) {
return isBSTUtil(root, INT_MIN, INT_MAX);
}
This code checks every node to see if it fits the BST rules by keeping track of allowed value ranges.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive visit of each node once.
- How many times: Exactly once per node in the tree.
As the number of nodes grows, the function checks each node once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The work grows directly with the number of nodes, so doubling nodes doubles work.
Time Complexity: O(n)
This means the time to check grows linearly with the number of nodes in the tree.
[X] Wrong: "Checking only left and right child values is enough to confirm BST."
[OK] Correct: This misses the rule that all left subtree nodes must be less than the current node and all right subtree nodes must be greater, not just immediate children.
Understanding how to check BST validity efficiently shows you can handle tree traversal and constraints clearly, a key skill in many coding challenges.
"What if we changed the code to check only immediate children without range limits? How would the time complexity change?"
Practice
Solution
Step 1: Understand BST property
A BST requires that for every node, values in the left subtree are smaller and values in the right subtree are larger.Step 2: Compare options with BST definition
For each node, all nodes in the left subtree are smaller and all nodes in the right subtree are larger matches the BST property exactly, while others describe different tree properties.Final Answer:
For each node, all nodes in the left subtree are smaller and all nodes in the right subtree are larger -> Option BQuick Check:
BST property = For each node, all nodes in the left subtree are smaller and all nodes in the right subtree are larger [OK]
- Confusing BST with balanced tree
- Thinking all nodes must have two children
- Assuming unique values define BST
Solution
Step 1: Identify typical BST check function parameters
Checking BST usually requires passing current node and min/max limits to validate subtree values.Step 2: Match function signatures
int isBST(struct Node* root, int min, int max); uses int return type and min/max parameters, which is common in C. bool isBST(struct Node* root, int min, int max); uses bool which is not standard C. Options B and C lack min/max parameters.Final Answer:
int isBST(struct Node* root, int min, int max); -> Option AQuick Check:
BST check needs min/max limits and int return [OK]
- Omitting min/max parameters
- Using bool type in plain C
- Using void return type for boolean check
struct Node {
int data;
struct Node* left;
struct Node* right;
};
int isBSTUtil(struct Node* node, int min, int max) {
if (node == NULL) return 1;
if (node->data <= min || node->data >= max) return 0;
return isBSTUtil(node->left, min, node->data) && isBSTUtil(node->right, node->data, max);
}
int isBST(struct Node* root) {
return isBSTUtil(root, INT_MIN, INT_MAX);
}
// Tree:
// 10
// / \
// 5 15
// / \
// 6 20
int main() {
struct Node n1 = {10, NULL, NULL};
struct Node n2 = {5, NULL, NULL};
struct Node n3 = {15, NULL, NULL};
struct Node n4 = {6, NULL, NULL};
struct Node n5 = {20, NULL, NULL};
n1.left = &n2; n1.right = &n3;
n3.left = &n4; n3.right = &n5;
printf("%d\n", isBST(&n1));
return 0;
}Solution
Step 1: Analyze tree structure and BST property
The node with value 6 is in the right subtree of 10 but less than 10, violating BST property.Step 2: Trace isBSTUtil calls
When checking node 6, min=15 and max=INT_MAX, 6 <= 15 fails the condition, so returns 0.Final Answer:
0 -> Option DQuick Check:
Node 6 violates BST rules, so output = 0 [OK]
- Ignoring subtree min/max constraints
- Assuming all left < root and right > root only locally
- Not tracing recursive calls carefully
int isBST(struct Node* root) {
if (root == NULL) return 1;
if (root->left != NULL && root->left->data >= root->data) return 0;
if (root->right != NULL && root->right->data <= root->data) return 0;
if (!isBST(root->left) || !isBST(root->right)) return 0;
return 1;
}Solution
Step 1: Understand current checks
The function only compares immediate children with root, missing deeper subtree violations.Step 2: Explain why min/max parameters are needed
To validate BST fully, we must ensure all nodes in left subtree < root and right subtree > root using min/max limits recursively.Final Answer:
Add min and max parameters to check entire subtree ranges -> Option AQuick Check:
Min/max limits fix subtree validation [OK]
- Checking only immediate children
- Ignoring subtree value ranges
- Misusing comparison operators
Solution
Step 1: Understand duplicate allowance rule
Duplicates allowed only on right subtree means left subtree nodes must be strictly less, right subtree nodes can be equal or greater.Step 2: Modify min/max checks accordingly
For left subtree, use node->data > min and < root->data; for right subtree, allow node->data >= root->data and < max.Final Answer:
Change the condition to allow node->data >= min and < max for right subtree -> Option CQuick Check:
Allow duplicates on right by using >= on right subtree [OK]
- Allowing duplicates on left subtree incorrectly
- Using strict inequalities everywhere
- Ignoring duplicate rules
Ready to prove it?
Pass the test and this pattern moves unknown
