Diameter of Binary Tree in DSA Javascript - 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 number of steps grow when the tree has more nodes?
Analyze the time complexity of the following code snippet.
function diameterOfBinaryTree(root) {
let diameter = 0;
function depth(node) {
if (!node) return 0;
const left = depth(node.left);
const right = depth(node.right);
diameter = Math.max(diameter, left + right);
return 1 + Math.max(left, right);
}
depth(root);
return diameter;
}
This code finds the longest path between any two nodes in a binary tree by calculating depths recursively.
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 one time.
As the number of nodes increases, the function visits each node once, so the total steps grow directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The steps grow in a straight line with the number of nodes.
Time Complexity: O(n)
This means the time to find the diameter grows directly with the number of nodes in the tree.
[X] Wrong: "The function visits nodes multiple times, so it must be slower than linear."
[OK] Correct: Each node is visited only once during the depth calculation, so the total work is proportional to the number of nodes.
Understanding this time complexity helps you explain how recursive tree algorithms scale, a common skill interviewers look for.
"What if we changed the code to calculate diameter by separately computing depths for each node without caching? 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, and node count is total nodes, both different from diameter.Final Answer:
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: Check common parameter naming
The function usually takes the root node as input, so a single parameter named root is standard.Step 2: Validate function signature correctness
function diameterOfBinaryTree(root) {} uses a clear, single parameter 'root' and a descriptive function name, matching common practice.Final Answer:
function diameterOfBinaryTree(root) {} -> Option DQuick Check:
Correct function signature uses root parameter [OK]
- Using multiple unrelated parameters
- Incorrect or unclear function names
- Missing parameters for the tree root
class TreeNode {
constructor(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
const root = new TreeNode(1,
new TreeNode(2,
new TreeNode(4),
new TreeNode(5)
),
new TreeNode(3)
);
function diameterOfBinaryTree(root) {
let diameter = 0;
function depth(node) {
if (!node) return 0;
const left = depth(node.left);
const right = depth(node.right);
diameter = Math.max(diameter, left + right);
return Math.max(left, right) + 1;
}
depth(root);
return diameter;
}
console.log(diameterOfBinaryTree(root));Solution
Step 1: Analyze the tree structure
The tree has root 1, left subtree with nodes 2,4,5 and right subtree with node 3. The longest path is from node 4 to node 3 through 2 and 1 (4->2->1->3), which has length 3 edges.Step 2: Trace the code logic
The code calculates diameter as max sum of left and right depths at each node. At node 2, left and right depths are 1 each, so diameter updates to 2. At root, left depth is 2, right depth is 1, so diameter updates to 3.Final Answer:
3 -> Option BQuick Check:
Longest path edges = 3 [OK]
- Counting nodes instead of edges for diameter
- Ignoring paths not passing through root
- Misreading tree structure
function diameterOfBinaryTree(root) {
let diameter = 0;
function depth(node) {
if (!node) return 0;
const left = depth(node.left);
const right = depth(node.right);
diameter = Math.max(diameter, left * right);
return Math.max(left, right) + 1;
}
depth(root);
return diameter;
}Solution
Step 1: Identify diameter update logic
The code updates diameter using left * right, which multiplies depths instead of adding them.Step 2: Correct diameter calculation
Diameter should be updated with left + right, representing the longest path through the node.Final Answer:
Using multiplication instead of addition for diameter update -> Option AQuick Check:
Diameter update uses addition, not multiplication [OK]
- Multiplying depths instead of adding
- Confusing depth return with diameter update
- Ignoring base case for null nodes
Solution
Step 1: Understand diameter path requirements
Diameter path is the longest path between any two nodes, so we must track paths from left and right subtrees.Step 2: Extend depth function to track paths
Along with depths, store paths for left and right subtrees. When diameter updates, combine these paths to form the diameter path.Step 3: Reject incorrect approaches
Height alone or BFS from root won't find longest path between any two nodes. Counting leaf nodes is unrelated.Final Answer:
Track left and right subtree depths and their paths; update diameter and store combined path when a longer diameter is found -> Option CQuick Check:
Track depths and paths to get diameter path [OK]
- Only tracking height or BFS from root
- Ignoring path storage during recursion
- Assuming diameter path is always root to leaf
Ready to prove it?
Pass the test and this pattern moves unknown
