Diameter of Binary Tree
Diameter of Binary Tree is LeetCode 543 (Easy). Given the root of a binary tree, return the diameter of a binary tree: the number of edges on the longest path between any two nodes.
- The path may or may not pass through the root.
- Length counts edges, not nodes, so a single node has diameter 0.
With up to 10⁴ nodes, recomputing heights at every node is O(n²); one post-order pass does it in O(n).
- The number of nodes in the tree is in the range [1, 10⁴].
- -100 <= Node.val <= 100
Intuition
Every path in a tree climbs to one highest node and then goes back down. Call that node the path's bend.
The longest path that bends at a node goes as deep as it can on both sides. If it can go l edges down on the left and r edges down on the right, that path has l + r edges. Trying every node as the bend covers every possible path, so the diameter of binary tree is the largest l + r found.
The usual height recursion already computes l and r at every node, so the check costs nothing extra. The one twist: the function returns the depth (what the parent needs) while the diameter is kept in a separate best.
"Longest path between any two nodes" of a tree is the bend pattern: the recursive function returns one arm (the depth) while a separate variable records the best path through each node. Binary Tree Maximum Path Sum uses the same split with node values instead of edge counts.
Approach
Before reading on: in [1,2,3,4,5], at which node does the longest path bend, and how many edges does it have? What must each child report so its parent can measure a path through itself?
Write the depth function
depth(node) returns the number of nodes on the longest downward path from node: 0 for an empty child, otherwise 1 + max(l, r). Seen from the parent, that same number counts the edges from the parent down to the deepest leaf on that side.
Finish both children first
Call depth on the left and right child before doing anything at the node (post-order). The node needs both numbers, l and r, before it can measure a path that bends through it.
Measure the path through this node
The longest path bending here has l + r edges: l down the left side plus r down the right. Update best = max(best, l + r). Do not add 1; that would count nodes instead of edges.
Return the depth, not the path
Return 1 + max(l, r). A path that bends here cannot also continue up to the parent, so the parent may only extend the deeper side. The diameter lives only in best.
Return best
When depth(root) finishes, every node has been tried as the bend, so best is the diameter. Each node is visited once: O(n) time, and O(h) stack space for a tree of height h.
Diameter of Binary Tree solution in Python | C++ | Java
best starts at 0: a single node is a path of 0 edges.best becomes 2.best becomes 3.best, which may bend anywhere in the tree.best starts at 0: a single node is a path of 0 edges.best becomes 1.best stays.best becomes 4.best stays.best, which may bend anywhere in the tree.best starts at 0: a single node is a path of 0 edges.best becomes 1.best, which may bend anywhere in the tree.Common pitfalls
Only checking the path through the root
return depth(root.left) + depth(root.right)
self.best = max(self.best, l + r) # at every node
In [1,2,null,3,4,5,null,null,6] the root has no right child, so the root-only answer is 3. The longest path, 5 → 3 → 2 → 4 → 6, bends at node 2 and has 4 edges.
Returning the path length to the parent
return l + r
self.best = max(self.best, l + r) return 1 + max(l, r)
The parent needs one arm it can extend. A path that already bends at this node cannot continue upward without visiting the node twice, so returning l + r inflates every depth above it.
Counting nodes instead of edges
self.best = max(self.best, l + r + 1)
self.best = max(self.best, l + r)
l and r already count the edges from this node down each side. Adding one returns 4 instead of 3 for [1,2,3,4,5].
Updating a plain local variable from the nested function
best = 0
def depth(node):
...
best = max(best, l + r)self.best = 0 # or: nonlocal best
Assigning to best inside depth makes Python treat it as a new local, so the first read raises UnboundLocalError. Store it on self or declare it nonlocal.
Edge cases
Both children report 0, so l + r = 0 and the diameter is 0: a path with no edges.
Complexity
Diameter of Binary Tree FAQ
Is there a simpler O(n²) way to find the diameter of a binary tree?
Yes. For every node, call a separate height function on its left and right child and add the two results; the diameter is the largest sum. It is easy to write, but height revisits the same subtrees again and again, so a chain of n nodes costs O(n²). The approach above gets both heights from one post-order pass, so each node is visited once.