Pattern #45

Tree Diameter

Important interview questions, thinking patterns, Postorder Height DFS, Subtree Diameter (Root exclusion), Two-Pass BFS trick, and Go code templates.

Must Solve

10 core questions — solve these first.

  1. 1.Diameter of Binary Tree
    easy
  2. 2.Diameter of N-ary Tree
    medium
  3. 3.Diameter of an Undirected Tree
    medium
  4. 4.Longest Path Between Any Two Tree Nodes
    medium
  5. 5.Binary Tree Maximum Path Sum
    hard
  6. 6.Longest Univalue Path
    medium
  7. 7.Tree Diameter Using Two BFS / DFS
    medium
  8. 8.Minimum Height Trees
    medium
  9. 9.Tree Distances
    hard
  10. 10.Farthest Node in a Tree
    medium

Also Important

5 more questions worth practicing.

  1. 11.Longest Path With Different Adjacent Characters
    hard
  2. 12.Longest ZigZag Path in a Binary Tree
    medium
  3. 13.Maximum Path Between Two Leaves
    hard
  4. 14.Weighted Tree Diameter
    medium
  5. 15.Tree DP Longest Path Variants
    medium

How to Think

  1. Need longest path between any two nodes?Tree Diameter
  2. Binary Tree?Postorder DFS + Height
  3. At each node?leftHeight + rightHeight
  4. General undirected tree?Two BFS / DFS passes

Go Tree Diameter Templates

Binary Tree Diameter (Postorder DFS) & General Undirected Tree (Two-Pass BFS) in Go

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// 1. Binary Tree Diameter (Single-Pass Postorder DFS)
func diameterOfBinaryTree(root *TreeNode) int {
    maxDiameter := 0

    var height func(node *TreeNode) int
    height = func(node *TreeNode) int {
        if node == nil {
            return 0
        }
        leftH := height(node.Left)
        rightH := height(node.Right)

        // Update global diameter (uses BOTH branches!)
        if leftH+rightH > maxDiameter {
            maxDiameter = leftH + rightH
        }

        // Return height upward (returns ONE branch!)
        return 1 + max(leftH, rightH)
    }

    height(root)
    return maxDiameter
}

// 2. General Undirected Tree Diameter (Two BFS Passes)
func treeDiameterUndirected(n int, edges [][]int) int {
    adj := make([][]int, n)
    for _, e := range edges {
        u, v := e[0], e[1]
        adj[u] = append(adj[u], v)
        adj[v] = append(adj[v], u)
    }

    bfs := func(start int) (int, int) {
        dist := make([]int, n)
        for i := range dist { dist[i] = -1 }
        queue := []int{start}
        dist[start] = 0
        farthestNode, maxD := start, 0

        for len(queue) > 0 {
            curr := queue[0]
            queue = queue[1:]
            for _, neighbor := range adj[curr] {
                if dist[neighbor] == -1 {
                    dist[neighbor] = dist[curr] + 1
                    if dist[neighbor] > maxD {
                        maxD = dist[neighbor]
                        farthestNode = neighbor
                    }
                    queue = append(queue, neighbor)
                }
            }
        }
        return farthestNode, maxD
    }

    farthestA, _ := bfs(0)
    _, diameter := bfs(farthestA)
    return diameter
}

👉 Total Time: O(N) | Space: O(H) / O(N)

Height vs Diameter & Single-Pass DFS

1. Height: Distance from a node downward to its deepest leaf (1 + max(left, right)).

2. Diameter: Longest path between any two nodes in the tree (leftHeight + rightHeight).

3. Single-Pass DFS: Do NOT recalculate heights separately for each node (which causes O(N²) time)! Compute height once in a postorder DFS while updating a global diameter candidate.

Two-Pass BFS Trick for Undirected Trees

For general undirected trees represented as adjacency lists:

Pass 1: Start at any arbitrary node X, run BFS to find the farthest node A (which is guaranteed to be one endpoint of a diameter).

Pass 2: Start at node A, run BFS to find the farthest node B. The distance between A and B is the tree diameter!

Visual Memory Rule
Tree Diameter   → Longest path between ANY two nodes (May NOT pass through Root!)
Binary Tree     → Candidate = leftHeight + rightHeight | Return = 1 + max(left, right)
Edges vs Nodes  → N nodes path = N-1 edges (Check problem definition!)
Undirected Tree → Two BFS passes (Arbitrary -> Farthest A -> Farthest B)

💡 Golden Rule: "Each node asks: ‘What is the deepest path from my left, and what is the deepest path from my right?’ Their sum may be the diameter."

Common Interview Mistakes

1. Assuming Diameter Must Pass Through Root

The longest path in a tree can live entirely inside a subtree! You MUST update the global diameter candidate at every node during DFS.

2. Returning Both Branches Upward

A parent node cannot extend a path that splits into two directions! The DFS return value MUST be single-branch height (1 + max(left, right)).

3. Recalculating Heights Separately

Calling a separate height(node) helper inside a loop causes O(N²) time complexity! Compute height and diameter together in 1 pass.

4. Confusing Edges vs Nodes Count

A path of K nodes contains K - 1 edges. Check whether the problem asks for number of edges or number of nodes!

Interview Rules

  1. 1. Longest path between any two nodes? → Tree Diameter
  2. 2. Binary Tree strategy? → Postorder DFS returning height
  3. 3. Candidate diameter at node?leftHeight + rightHeight
  4. 4. Return value upward to parent?1 + max(leftHeight, rightHeight)
  5. 5. Passes through root? → Not necessarily! Update global max at every node
  6. 6. General undirected tree strategy?→ Two BFS/DFS passes (Arbitrary -> Farthest A -> Farthest B)
  7. 7. Max Path Sum comparison? → Max Path Sum sums node values; Diameter sums edge counts
  8. 8. Overall Complexity → Time: O(N) | Stack Space: O(H) (O(log N) balanced, O(N) skewed)

Small Rules

  1. Rule 1: Tree Diameter is the longest path between any two nodes.
  2. Rule 2: Diameter does not need to pass through the root node.
  3. Rule 3: At every node, diameter candidate = leftHeight + rightHeight.
  4. Rule 4: DFS return value = 1 + max(leftHeight, rightHeight).
  5. Rule 5: Two BFS/DFS passes find diameter endpoints in general undirected trees.

Production Thinking

Network Topology LatencyCalculating worst-case hop count between any two nodes in a tree network

Organization Separation DistanceMeasuring maximum managerial distance between two employees across departments

Dependency Separation RadiusDetermining largest separation distance between two leaf package dependencies

Distributed Broadcast BoundFinding maximum propagation delay for tree-structured broadcast topologies

Remember This

Tree Diameter   → Longest path
Binary Tree     → Postorder DFS
Left + Right    → Candidate diameter
Return          → 1 + max(left, right)
Global answer   → Update everywhere
Root            → Not necessarily on path
General Tree    → BFS/DFS twice
Time            → O(N)

💡 Golden Rule: "Each node asks: ‘What is the deepest path from my left, and what is the deepest path from my right?’ Their sum may be the diameter."