Binary Trees · 4 of 35
Diameter of a tree
Find the longest walk between any two nodes of a tree, by asking at every node how tall its two sides are.
- Simple way
- time O(n^2)
room O(h) - Clever way
- time O(n)
room O(h)
The problem, simply
You get a binary tree. A path is a walk along the branches from one node to another, never using a branch twice. Its length is the number of branches (edges) it uses.
The diameter is the length of the longest path in the tree. That path does not have to go through the root.
Some books count nodes instead of edges. Then the answer is one more. Ask which one the interviewer wants. Here we count edges, like LeetCode 543.
A story to remember it
Picture it
The longest path is 8, 6, 4, 2, 5, 7, 9. It uses 6 edges and bends at 2. Going through the root 1 gives only 5 edges.
- answer
- path
Examples
Through the root
- In
[1, 2, 3, 4, 5]- Out
3
4, 2, 1, 3 (or 5, 2, 1, 3) uses 3 edges.
Not through the root
- In
[1, 2, 3, 4, 5, null, null, 6, null, null, 7, 8, null, null, 9]- Out
6
The best path bends at 2. The root's best is only 4 + 1 = 5.
Two nodes
- In
[1, 2]- Out
1
One edge.
One node
- In
[1]- Out
0
A path from a node to itself uses no edges.
Empty tree
- In
[]- Out
0
Nothing to walk.
Way 1: the simple way
At every node, measure the height of the left side and of the right side from scratch. Their sum is the longest path bending at that node. Keep the biggest one over all nodes.
height(n)is 0 for an empty node, else1 + max(height(left), height(right)).- At each node, the path bending here is
height(left) + height(right). - The answer is the biggest of that value, the left side's answer and the right side's answer.
class Solution {
public int diameter(TreeNode root) {
if (root == null) return 0;
int here = height(root.left) + height(root.right); // bends at root
return Math.max(here, Math.max(diameter(root.left), diameter(root.right)));
}
private int height(TreeNode n) {
if (n == null) return 0;
return 1 + Math.max(height(n.left), height(n.right));
}
}How long it takes: every node measures everything below it again. In a stick shaped tree that is O(n^2). Extra room: the waiting helpers, O(h).
Way 2: the clever way
Measure each height once, from the bottom up, and check the bending path at the same time. The helper returns a height, and it updates a "best so far" on the side.
- An empty spot returns height 0.
- Get the left height
Land the right heightR. - The path bending here has
L + Redges. If it beatsbest, save it. - Return
1 + max(L, R)to the parent.
Heights go up, the best bend is remembered
01 / 11
Each helper returns the height of its subtree: how many nodes from it down to its deepest leaf. While it is at it, it checks the longest path that bends at its own node: left height + right height.
- best
- 0
- looking now
- done
- answer
- path
- ignored
class Solution {
private int best;
public int diameter(TreeNode root) {
best = 0;
height(root);
return best;
}
// returns the height, and checks the path that bends at n
private int height(TreeNode n) {
if (n == null) return 0;
int left = height(n.left);
int right = height(n.right);
best = Math.max(best, left + right); // edges in the path bending here
return 1 + Math.max(left, right);
}
}How long it takes: each node is visited once, O(n). Extra room: the waiting helpers, O(h).
Watch out for
- Edges or nodes. With heights counted in nodes,
left + rightis the number of edges. If the problem wants nodes, returnbest + 1. - Only checking the root. The longest path may bend anywhere.
- Forgetting to reset
bestbetween calls when it is a field.
What interviewers ask next
- Return the path itself? Also remember which node gave the best bend, then walk down the taller side twice from it.
- Maximum path sum (values can be negative)? Same shape: return the best downward sum (never below 0), and update the best with
node + left + right. That is LeetCode 124. - Diameter of a general tree or a graph that is a tree? Run a search from any node to find the farthest node
a, then search froma. The farthest distance fromais the diameter. - Longest path where all values are equal? Same idea, but a side counts only when the child has the same value (LeetCode 687).
Remember this
Grown-up words: the rope is a path, its length in branches is the number of edges, the longest one is the diameter, the bend is the path's topmost node, and asking children first is post order traversal.