Diameter of Binary Tree in DSA C - Time & Space Complexity
We want to know how the time to find the diameter of a binary tree grows as the tree gets bigger.
The question is: how many steps does it take to check all nodes and find the longest path?
Analyze the time complexity of the following code snippet.
int max(int a, int b) {
return (a > b) ? a : b;
}
int height(struct Node* root, int* diameter) {
if (!root) return 0;
int leftHeight = height(root->left, diameter);
int rightHeight = height(root->right, diameter);
*diameter = max(*diameter, leftHeight + rightHeight);
return max(leftHeight, rightHeight) + 1;
}
int diameterOfBinaryTree(struct Node* root) {
int diameter = 0;
height(root, &diameter);
return diameter;
}
This code finds the diameter by calculating the height of each subtree and updating the longest path found.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls to visit each node once.
- How many times: Each node is visited exactly once to calculate heights and update diameter.
As the number of nodes grows, the function visits each node once, doing a small fixed amount of work per node.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The work grows linearly with the number of nodes.
Time Complexity: O(n)
This means the time to find the diameter grows directly in proportion to the number of nodes in the tree.
[X] Wrong: "The diameter calculation takes more than linear time because it checks many paths repeatedly."
[OK] Correct: The code visits each node once, calculating height and updating diameter on the fly, so it does not repeat work unnecessarily.
Understanding this helps you explain how recursion can efficiently solve tree problems by visiting nodes once, a key skill in many coding challenges.
"What if the code recalculated height separately for left and right subtrees without storing results? How would the time complexity change?"
Practice
Solution
Step 1: Understand the diameter concept
The diameter is the longest path between any two nodes, which may or may not pass through the root.Step 2: Differentiate from height and node count
Height is longest path from root to leaf, leaf count is number of leaves, total nodes is size. Diameter is distinct.Final Answer:
The length of the longest path between any two nodes in the tree -> Option CQuick Check:
Diameter = longest path length [OK]
- Confusing diameter with height
- Thinking diameter counts nodes instead of edges
- Assuming diameter always passes through root
Solution
Step 1: Check parameter type for tree node
In C, tree nodes are passed as pointers to struct Node, so parameter should be struct Node* root.Step 2: Check return type and parameter correctness
Height returns int, so return type int is correct. Passing pointer is correct, not struct by value.Final Answer:
int height(struct Node* root); -> Option AQuick Check:
Pointer parameter and int return type [OK]
- Passing struct Node by value instead of pointer
- Using void return type instead of int
- 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 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
}
int diameter(struct Node* root) {
if (!root) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
int leftDiameter = diameter(root->left);
int rightDiameter = diameter(root->right);
int maxDiameter = leftHeight + rightHeight + 1;
if (leftDiameter > maxDiameter) maxDiameter = leftDiameter;
if (rightDiameter > maxDiameter) maxDiameter = rightDiameter;
return maxDiameter;
}
int main() {
struct Node n1 = {1, NULL, NULL};
struct Node n2 = {2, NULL, NULL};
struct Node n3 = {3, &n1, &n2};
printf("%d", diameter(&n3));
return 0;
}Solution
Step 1: Analyze tree structure
Root n3 has two children n1 and n2, both leaves. Height of left and right subtree is 1 each.Step 2: Calculate diameter
Diameter = max of (leftHeight + rightHeight + 1, leftDiameter, rightDiameter) = max(1+1+1, 1, 1) = 3.Final Answer:
3 -> Option DQuick Check:
Diameter = 3 nodes in longest path [OK]
- Confusing diameter with height
- Forgetting to add 1 for root node in diameter
- Using height instead of diameter in comparisons
int diameter(struct Node* root) {
if (!root) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
int leftDiameter = diameter(root->left);
int rightDiameter = diameter(root->right);
int maxDiameter = leftHeight + rightHeight;
if (leftDiameter > maxDiameter) maxDiameter = leftDiameter;
if (rightDiameter > maxDiameter) maxDiameter = rightDiameter;
return maxDiameter;
}Solution
Step 1: Check diameter calculation formula
Diameter includes edges between nodes, so it should add 1 for the root node connecting left and right paths.Step 2: Identify missing +1 in maxDiameter
Current code misses +1, so maxDiameter undercounts by 1.Final Answer:
maxDiameter should be leftHeight + rightHeight + 1 -> Option BQuick Check:
Diameter = leftHeight + rightHeight + 1 [OK]
- Omitting +1 in diameter calculation
- Confusing height and diameter returns
- Not handling null root base case
Solution
Step 1: Modify height to return max sum path
Instead of counting nodes, height returns max sum of node values from root to leaf recursively.Step 2: Update diameter to sum left and right max sums plus root value
Diameter becomes max of leftDiameter, rightDiameter, and leftSum + rightSum + root's value.Final Answer:
Change height function to return max sum of node values from root to leaf, and update diameter to sum left and right max sums plus root's value -> Option AQuick Check:
Diameter by sum = max path sum through root [OK]
- Multiplying diameter by root value incorrectly
- Ignoring node values in diameter calculation
- Adding all node values separately instead of path sums
Ready to prove it?
Pass the test and this pattern moves unknown
