Check if Binary Tree is Balanced in DSA C - Time & Space Complexity
We want to know how long it takes to check if a binary tree is balanced.
Specifically, how the time grows as the tree gets bigger.
Analyze the time complexity of the following code snippet.
int height(struct Node* root) {
if (root == NULL) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
}
int isBalanced(struct Node* root) {
if (root == NULL) return 1;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
if (abs(leftHeight - rightHeight) > 1) return 0;
return isBalanced(root->left) && isBalanced(root->right);
}
This code checks if a binary tree is balanced by comparing heights of left and right subtrees recursively.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
heightfunction is called repeatedly for each node. - How many times: For each node,
heightis called again on its children, causing repeated calculations.
Each node causes calls to height on its subtrees, which themselves call height on their subtrees, repeating work.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 calls to height |
| 100 | About 10,000 calls to height |
| 1000 | About 1,000,000 calls to height |
Pattern observation: The number of operations grows roughly with the square of the number of nodes.
Time Complexity: O(n²)
This means the time to check balance grows very quickly as the tree gets bigger because heights are recalculated many times.
[X] Wrong: "The function runs in linear time because it visits each node once."
[OK] Correct: The height function is called many times for the same nodes, causing repeated work and making the total time much larger.
Understanding this helps you explain why some recursive solutions can be slow and how to improve them, a key skill in interviews.
"What if we modified the code to calculate height and check balance in the same recursion? How would the time complexity change?"
Practice
Solution
Step 1: Understand balance condition
A balanced binary tree means the height difference between left and right subtrees of every node is at most 1.Step 2: Compare other options
Other options describe different tree properties but not the balance condition.Final Answer:
The height difference between left and right subtrees of every node is at most 1 -> Option AQuick Check:
Balance means height difference ≤ 1 [OK]
- Confusing balanced with complete tree
- Thinking balance means equal number of nodes
- Assuming all nodes must have two children
Solution
Step 1: Check parameter type
The function should take a pointer to the root node: struct Node* root.Step 2: Check return type
Return type int is common for boolean checks in C (0 or 1).Final Answer:
int isBalanced(struct Node* root); -> Option DQuick Check:
Pointer parameter and int return type [OK]
- Passing struct by value instead of pointer
- Using void return type for boolean check
- Missing struct keyword in parameter
struct Node {
int data;
struct Node* left;
struct Node* right;
};
int height(struct Node* root) {
if (!root) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
int isBalanced(struct Node* root) {
if (!root) return 1;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
if (abs(leftHeight - rightHeight) > 1) return 0;
return isBalanced(root->left) && isBalanced(root->right);
}
// Tree:
// 1
// / \
// 2 3
// /
// 4
int main() {
struct Node n4 = {4, NULL, NULL};
struct Node n2 = {2, &n4, NULL};
struct Node n3 = {3, NULL, NULL};
struct Node n1 = {1, &n2, &n3};
printf("%d", isBalanced(&n1));
return 0;
}Solution
Step 1: Calculate heights of subtrees
Node 2's left subtree height is 1 (node 4), right subtree is 0, difference 1 ≤ 1. Node 1's left subtree height is 2, right subtree height is 1, difference 1 ≤ 1.Step 2: Check balance recursively
All nodes satisfy balance condition, so isBalanced returns 1 (true).Final Answer:
1 -> Option CQuick Check:
Height difference ≤ 1 at all nodes means balanced [OK]
- Ignoring recursive balance check on subtrees
- Miscomputing height values
- Assuming difference > 0 means unbalanced
int height(struct Node* root) {
if (!root) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return leftHeight + rightHeight + 1;
}
int isBalanced(struct Node* root) {
if (!root) return 1;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
if (abs(leftHeight - rightHeight) > 1) return 0;
return isBalanced(root->left) && isBalanced(root->right);
}Solution
Step 1: Analyze height function logic
The height function incorrectly returns leftHeight + rightHeight + 1 instead of max(leftHeight, rightHeight) + 1.Step 2: Understand impact on balance check
Incorrect height causes wrong height difference, leading to wrong balance result.Final Answer:
height function incorrectly sums left and right heights -> Option BQuick Check:
Height = max(left, right) + 1, not sum [OK]
- Summing heights instead of taking max
- Ignoring NULL checks (though present here)
- Confusing return types for boolean
isBalanced efficiently.Solution
Step 1: Understand naive approach
Calculating height separately for each node causes repeated work and O(n²) time complexity.Step 2: Efficient approach
Using a helper function that returns both height and balance status in one traversal reduces time to O(n).Final Answer:
Use a helper function that returns height and balance status simultaneously in one traversal -> Option AQuick Check:
Single traversal with combined info is efficient [OK]
- Recomputing heights multiple times
- Ignoring subtree balance checks
- Using node counts instead of heights
Ready to prove it?
Pass the test and this pattern moves unknown
