Diameter of Binary Tree
Return the length (in edges) of the longest path between any two nodes — it need not pass the root.
Open on LeetCode ↗Intuition
The longest path bends at some node: left depth + right depth through it. Compute depth recursively and, at every node, test leftDepth + rightDepth as a diameter candidate — one DFS answers both questions at once.
Structurally identical to binary-tree-maximum-path-sum: what you return (depth of one arm) differs from what you record (the bend through this node). Any time the global answer can pass through a node using both children, but a parent can only receive one arm, split the two quantities like this.
Approach
Depth is the helper
depth(node) = 1 + max(depth(left), depth(right)). That's the standard recursion.
Diameter rides along
While unwinding, each node knows both child depths — their sum is the best path bending there. Track the global max in a side variable.
Return depth, record diameter
The recursion's return value stays pure (depth); the answer is collected as a side effect — a common DFS pattern.
Solution & live demo
Common pitfalls
Returning the combined width to the parent
return l + r
self.best = max(self.best, l + r) return 1 + max(l, r)
A path that already bent through this node can't continue upward without revisiting it. The parent needs a single descending arm — the bend is recorded globally and never propagated.
Forgetting the 1 + on the returned depth
return max(l, r)
return 1 + max(l, r)
The current node adds one edge to whichever arm the parent extends. Without it every depth is zero and the diameter comes back 0.
Counting nodes instead of edges
self.best = max(self.best, l + r + 1)
self.best = max(self.best, l + r)
The problem defines diameter as the number of edges on the longest path. Since l and r are already edge counts to the deepest leaves, their sum is the answer — adding one reports the node count instead.
Edge cases
No edges → diameter 0.
Best 'bend' is at the top: one side deep, other 0 — equals the chain length.