Diameter of Binary Tree in DSA C# - Time & Space Complexity
We want to understand how the time needed to find the diameter of a binary tree changes as the tree grows.
Specifically, how does the work increase when the tree has more nodes?
Analyze the time complexity of the following code snippet.
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val=0) { this.val = val; }
}
int diameter = 0;
int Depth(TreeNode node) {
if (node == null) return 0;
int leftDepth = Depth(node.left);
int rightDepth = Depth(node.right);
diameter = Math.Max(diameter, leftDepth + rightDepth);
return Math.Max(leftDepth, rightDepth) + 1;
}
// Call Depth(root) to compute diameter
This code finds the longest path between any two nodes in a binary tree by computing depths recursively.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls to Depth for each node.
- How many times: Each node is visited once to calculate depth and update diameter.
As the number of nodes increases, the function visits each node once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 calls |
| 100 | About 100 calls |
| 1000 | About 1000 calls |
Pattern observation: The work grows directly with the number of nodes, so doubling nodes roughly doubles the work.
Time Complexity: O(n)
This means the time to find the diameter grows linearly with 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 depth and updating diameter on the fly, so it does not repeat work for the same nodes.
Understanding this linear time solution shows you can efficiently handle tree problems using recursion and careful tracking, a key skill in many coding challenges.
"What if we changed the code to compute diameter by separately computing depths for each node multiple times? 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 the longest path from root to leaf, node count is total nodes, and leaf count is number of leaves, none of which define diameter.Final Answer:
The length of the longest path between any two nodes in the tree -> Option AQuick Check:
Diameter = longest path between nodes [OK]
- Confusing diameter with tree height
- Thinking diameter counts nodes instead of edges
- Assuming diameter must pass through root
Solution
Step 1: Review C# method signature syntax
In C#, method signature starts with access modifier, return type, method name, and parameters in parentheses.Step 2: Check each option
public int Diameter(TreeNode root) follows correct syntax: public int Diameter(TreeNode root). Others have incorrect order or missing parts.Final Answer:
public int Diameter(TreeNode root) -> Option DQuick Check:
Correct C# method syntax = public int Diameter(TreeNode root) [OK]
- Placing return type after parameters
- Omitting access modifier or return type
- Incorrect order of keywords
class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int v) { val = v; }
}
// Tree structure:
// 1
// / \
// 2 3
// /
// 4
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
int diameter = CalculateDiameter(root); // Assume CalculateDiameter correctly implemented
Console.WriteLine(diameter);Solution
Step 1: Visualize the tree and longest path
The longest path is from node 4 to node 3: path length = edges 4->2->1->3 = 3 edges.Step 2: Calculate diameter as number of edges
Diameter counts edges, so longest path length is 3.Final Answer:
3 -> Option AQuick Check:
Longest path edges = 3 [OK]
- Counting nodes instead of edges
- Assuming diameter passes through root only
- Ignoring one side of the tree
int maxDiameter = 0;
int Depth(TreeNode node) {
if (node == null) return 0;
int left = Depth(node.left);
int right = Depth(node.right);
maxDiameter = Math.Max(maxDiameter, left + right + 1);
return Math.Max(left, right) + 1;
}
int Diameter(TreeNode root) {
Depth(root);
return maxDiameter;
}Solution
Step 1: Understand diameter counting edges vs nodes
The code adds left + right + 1 (nodes), but diameter counts edges, so subtract 1.Step 2: Fix return value in Diameter method
Return maxDiameter - 1 to convert node count to edge count for diameter.Final Answer:
Diameter should be maxDiameter - 1 because diameter counts edges, not nodes -> Option BQuick Check:
Diameter edges = nodes - 1 [OK]
- Returning maxDiameter directly without subtracting 1
- Changing base case return value incorrectly
- Resetting maxDiameter inside recursive calls
Solution
Step 1: Understand diameter and path relationship
Diameter is longest path between any two nodes, so tracking path during recursion helps capture it.Step 2: Extend recursion to return depth and path
Modify recursive calls to return depth and path list; update max path when a longer diameter is found.Step 3: Compare other options
Calculate diameter first, then do a separate BFS to find the path is inefficient; C only finds longest root-to-leaf path, not diameter; D is unrelated to diameter.Final Answer:
Modify the recursive function to return both depth and path, updating max path when diameter increases -> Option CQuick Check:
Track depth and path together for diameter path [OK]
- Trying to find path after diameter without tracking during recursion
- Confusing longest root-to-leaf path with diameter
- Using BFS level order traversal which doesn't find diameter
Ready to prove it?
Pass the test and this pattern moves unknown
