Sale: Get 60% Off on all Pro Plans. Buy Now

Diameter of Binary Tree

Easy DFS

Problem

Given the root of a binary tree, return the length of the diameter of the tree, where the diameter is defined as the length of the longest path between any two nodes in the tree. The path may or may not pass through the root.

  • The number of nodes in the tree is in the range [1, 10⁴]
  • −100 ≤ Node.val ≤ 100

Example

Input: root = [1,2,3,4,5]
Output: 3

The longest path is [4,2,1,3] or [5,2,1,3], both with length 3 edges. The algorithm uses DFS to compute the depth of left and right subtrees for each node, updating the maximum diameter found as the sum of left and right depths. For example, at node 2, left depth is 1 (node 4), right depth is 1 (node 5), so diameter candidate is 2. At root 1, left depth is 2, right depth is 1, so diameter candidate is 3, which is the maximum.

Approach

Straightforward Solution

A brute-force approach would compute the longest path by checking all pairs of nodes, which is O(n^2) and inefficient for large trees.

Core Observation

The diameter of a binary tree is the maximum sum of the depths of the left and right subtrees at any node. This is because the longest path between two nodes passes through their lowest common ancestor, and the path length is the sum of the depths of the two subtrees rooted at that ancestor.

Path to Optimal

Preview

The key insight is to use a post-order DFS traversal to compute the depth of each subtree while simultaneously updating the maximum diameter found so far. At each node, the diameter candidate is the sum of the left and right subtree depths…

Full step-by-step walkthrough on Pro

Optimal Approach

Preview

Perform a DFS that returns the depth of the subtree rooted at the current node. During the recursion, update a global variable to track the maximum diameter found as the sum of left and right subtree depths at each node…

Full step-by-step walkthrough on Pro

Want the full reasoning chain?

Unlock the complete walkthrough, line-by-line analysis, and recall drill.

Unlock Pro

Time

O(n)

Each node is visited exactly once during the DFS traversal, and constant work is done per node.

Space

O(h)

The recursion stack uses space proportional to the height of the tree, which is O(h). In the worst case (skewed tree), h can be O(n), but for balanced trees, h is O(log n).

Pattern Spotlight

DFS (Post-Order Traversal with State Propagation)

When a problem requires combining information from subtrees to compute a global property (like diameter), use post-order DFS to gather subtree results and propagate state upward, updating global answers along the way.

Solution

Python
1class Solution:
2 def diameterOfBinaryTree(self, root: TreeNode) -> int:
3 res = 0
4
5 def dfs(root):
6 nonlocal res
7 if not root:
8 return 0
9
10 left = dfs(root.left)
11 right = dfs(root.right)
12
13 res = max(res, left + right)
14
15 return 1 + max(left, right)
16
17 dfs(root)
18 return res

Step-by-Step Solution

1

Initialize Diameter Tracker and Define DFS to Compute Subtree Depths

3res = 0
5def dfs(root):
6 nonlocal res
7 if not root:
8 return 0

Objective

To set up a variable to track the maximum diameter found and define a recursive DFS function that computes subtree depths while updating this diameter.

Key Insight

Using a nonlocal variable allows the DFS function to update the global maximum diameter during recursion. The DFS returns the depth of the subtree rooted at the current node, enabling the calculation of diameter candidates as the sum of left and right depths. This design tightly couples depth calculation with diameter tracking, enabling a single-pass solution.

Interview Quick-Check

Core Logic

The DFS returns the maximum depth of the current node's subtrees, while updating the global diameter as the sum of left and right depths.

State & Boundaries

The base case returns 0 for null nodes, representing zero depth.

Common Pitfalls & Bugs

Forgetting to use a nonlocal or global variable for diameter tracking would prevent updates from propagating outside the DFS function.

2

Recursively Compute Left and Right Subtree Depths and Update Diameter

To recursively compute the depths of left and right subtrees, update the maximum diameter with their sum, and return the depth of the current subtree.

3

Invoke DFS on Root and Return Final Diameter

To start the DFS traversal from the root and return the computed maximum diameter after traversal completes.

2 more steps with full analysis available on Pro.

Line Analysis

This solution has 3 Critical lines interviewers watch for.

Line 13 Critical
res = max(res, left + right)

Update the global diameter with the sum of left and right depths if larger.

This line is the core algorithmic move: it considers the longest path passing through the current node by summing left and right depths, updating the global maximum diameter accordingly.

Line 6 Critical
nonlocal res

Declare that the DFS function will modify the nonlocal diameter variable.

Using 'nonlocal' allows the DFS function to update the diameter variable defined in the outer scope, enabling global state tracking during recursion.

Line 15 Critical
return 1 + max(left, right)

Return the depth of the current subtree as 1 plus the maximum of left and right depths.

Returning this value allows parent calls to correctly compute their subtree depths, enabling the recursive propagation of depth information necessary for diameter calculation.

Full line-by-line criticality + rationale for all 11 lines available on Pro.

Test Your Understanding

Why does summing the depths of the left and right subtrees at each node correctly compute the diameter?

See the answer with Pro.

Related Problems

DFS pattern

Don't just read it. Drill it.

Reconstruct Diameter of Binary Tree from memory until it sticks. AlgoDrill blanks out key lines and makes you fill them back in, step by step.

Unlock the Diameter of Binary Tree drill

or drill a free problem