Skip to content

191. Minimum Height Trees

๐Ÿ”— LeetCode Problem: 310. Minimum Height Trees
๐Ÿ“Š Difficulty: Medium
๐Ÿท๏ธ Topics: Graph, BFS, Tree, Topological Sort, Tree Centers

Problem Statement

A tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.

Given a tree of n nodes labeled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [aแตข, bแตข] indicates that there is an undirected edge between the two nodes aแตข and bแตข in the tree, you can choose any node of the tree as the root.

When you select a node x as the root, the result tree has height h. Among all possible rooted trees, those with minimum height (i.e., min(h)) are called minimum height trees (MHTs).

Return a list of all MHTs' root labels. You can return the answer in any order.

The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

Example 1:

Input: n = 4, edges = [[1,0],[1,2],[1,3]]

Output: [1]

Explanation:
  Tree structure:
       0
       |
       1
      / \
     2   3

  If root = 0: height = 3 (0โ†’1โ†’2 or 0โ†’1โ†’3)
  If root = 1: height = 1 (1โ†’0, 1โ†’2, or 1โ†’3) โœ… MINIMUM!
  If root = 2: height = 3 (2โ†’1โ†’0 or 2โ†’1โ†’3)
  If root = 3: height = 3 (3โ†’1โ†’0 or 3โ†’1โ†’2)

  MHT roots: [1]

Example 2:

Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]

Output: [3,4]

Explanation:
  Tree structure:
    0   1   2
     \ | /
      \|/
       3---4---5

  If root = 3: height = 2 โœ…
  If root = 4: height = 2 โœ…
  Other roots: height > 2

  MHT roots: [3, 4]

Constraints: - 1 <= n <= 2 * 10โด - edges.length == n - 1 - 0 <= aแตข, bแตข < n - aแตข != bแตข - All the pairs (aแตข, bแตข) are distinct. - The given input is guaranteed to be a tree and there will be no repeated edges.


๐ŸŒณ Visual Understanding - The Complete Picture

The Problem We're Solving ๐Ÿค”

Given an undirected tree, find root(s) that minimize height: ๐ŸŒณ

Example tree (n=4):
    0
    |
    1
   / \
  2   3

Different roots, different heights:

Root at 0:          Root at 1:
    0                   1
    |                  /|\
    1                 0 2 3
   / \              
  2   3           Height = 1 โœ… MINIMUM!
Height = 3

Root at 2:          Root at 3:
    2                   3
    |                   |
    1                   1
   / \                 / \
  0   3               0   2
Height = 3        Height = 3

Question: Which root(s) give minimum height? ๐ŸŽฏ
Answer: Node 1 with height 1! โœ…

Building Understanding Through Examples ๐Ÿ“š

Example 1: Star graph (center wins)

Tree:
    0
    |
    1---2
    |
    3

Rooted at 0: height = 3
Rooted at 1: height = 1 โœ… CENTER!
Rooted at 2: height = 3
Rooted at 3: height = 3

MHT root: [1] (the center node)
Example 2: Linear chain (middle wins)

Tree: 0---1---2---3---4

Rooted at 0: height = 4
Rooted at 1: height = 3
Rooted at 2: height = 2 โœ… MIDDLE!
Rooted at 3: height = 3
Rooted at 4: height = 4

MHT root: [2] (the center node)
Example 3: Even-length chain (two centers)

Tree: 0---1---2---3

Rooted at 1: height = 2 โœ…
Rooted at 2: height = 2 โœ…

MHT roots: [1, 2] (both center nodes!)
Visual Insight: Peeling Onion Layers ๐Ÿง…

Start:
    0   1   2
     \ | /
      \|/
       3---4---5

Level 0 (leaves): {0, 1, 2, 5}
Remove leaves:
       3---4

Level 1 (new leaves): {3, 4}
These are the centers! โœ…

MHT roots: [3, 4]

Pattern: Remove leaves layer by layer
         Last 1-2 nodes = centers!

The Pattern Emerges ๐Ÿ’ก

Key observations: ๐Ÿ”

1๏ธโƒฃ Tree Centers = MHT Roots ๐ŸŽฏ
   The center(s) of the tree minimize height
   At most 2 centers in any tree!

2๏ธโƒฃ Topological Sort Variation ๐Ÿ”„
   Like Kahn's algorithm
   But remove LEAVES instead of zero in-degree
   Process layer by layer!

3๏ธโƒฃ Peeling From Outside ๐Ÿง…
   Start with leaf nodes (degree 1)
   Remove them, find new leaves
   Continue until 1-2 nodes remain

4๏ธโƒฃ Why At Most 2 Centers? ๐Ÿค”
   If 3+ centers: one must be closer to periphery
   Contradiction! Can have 1 or 2 only!

5๏ธโƒฃ Similar to Kahn's But Different ๐Ÿ”„
   Kahn's: directed graph, in-degree 0
   MHT: undirected tree, degree 1 (leaves)

๐Ÿง  The Journey From Brute Force to Optimal

Part 1: The Obvious Try - "Try every root?" ๐Ÿค”

๐Ÿ’ญ First thought: "Root at each node, calculate height!"

Brute force:
  For each node as root:
    BFS/DFS to find max depth (height)
    Track minimum height and corresponding roots

  Return roots with minimum height

Example:
  n = 4, edges = [[1,0],[1,2],[1,3]]

  Root 0: BFS finds max depth = 3
  Root 1: BFS finds max depth = 1 โœ…
  Root 2: BFS finds max depth = 3
  Root 3: BFS finds max depth = 3

  Minimum = 1, root = [1]

Problem: TOO SLOW! ๐Ÿ˜ฑ

Time complexity:
  For each of n nodes: O(n) BFS/DFS
  Total: O(nยฒ) ๐ŸŒ

For 20,000 nodes: 400,000,000 operations! โŒ

Can we do better? ๐Ÿค”

Part 2: The Realization - "Centers minimize height!" ๐Ÿ’ญ

๐Ÿค” Key insight: What makes a good root?

Think geometrically:
  Best root = CENTER of the tree!

Why?
  Center = equidistant from all extremes
  Minimizes maximum distance to any node
  = Minimizes height! ๐ŸŽฏ

Example:
  Linear chain: 0---1---2---3---4

  Center node 2:
    Max distance to any node = 2
    (2 to 0 or 2 to 4)

  Non-center node 0:
    Max distance to node 4 = 4
    Much worse!

So the question becomes:
  "How to find the CENTER of a tree?"

This is a CLASSIC graph theory problem! ๐ŸŒŸ

Part 3: The Algorithm - "Peel like an onion!" ๐Ÿ’ก

๐Ÿค” Finding tree centers: Layer-by-layer removal!

Algorithm (similar to topological sort):
  1. Start with all leaf nodes (degree 1)
  2. Remove leaves, find new leaves
  3. Continue until 1-2 nodes remain
  4. These are the centers! ๐ŸŽฏ

Why this works:
  Leaves are farthest from center
  Remove them, move one layer inward
  Keep peeling until reaching center!

Example:
  Tree:
      0   1   2
       \ | /
        \|/
         3---4---5

  Degrees: [1, 1, 1, 3, 2, 1]
  Leaves: {0, 1, 2, 5}

  Round 1: Remove leaves {0, 1, 2, 5}
           Remaining: {3, 4}
           Update degrees: [-, -, -, 1, 1, -]
           New leaves: {3, 4}

  Round 2: Only 2 nodes left! STOP! โœ…
           Centers: {3, 4}

Intuition: Squeeze from outside toward center! ๐Ÿง…

Part 4: The Implementation - "Track degrees like Kahn's!" ๐Ÿ’ก

๐Ÿค” Implementation details:

Similar to Kahn's algorithm structure:

1. Calculate degrees (undirected graph)
   degree[i] = number of neighbors

2. Queue all leaves (degree 1)
   Special case: single node (degree 0) is also a leaf!

3. BFS-style layer removal:
   while (n > 2):  // More than 2 nodes remain
     size = queue.size()
     n -= size  // Remove this layer

     for each leaf in current layer:
       for each neighbor:
         degree[neighbor]--
         if degree[neighbor] == 1:
           queue.add(neighbor)  // New leaf!

4. Remaining nodes (1 or 2) are centers! ๐ŸŽฏ

Key differences from Kahn's:
  - Undirected graph (degree, not in-degree)
  - Stop at 1-2 nodes (not 0)
  - Process by layers (reduce n)

Time: O(n) - visit each node once! โšก
Much better than O(nยฒ)! ๐Ÿš€

Part 5: The Pattern - "Tree center finding!" ๐ŸŽฏ

โœจ This is a TREE CENTER problem!

Pattern recognition:
  โœ… Undirected tree
  โœ… Find node(s) that minimize some property
  โœ… Center-based optimization
  โœ… Layer-by-layer BFS

Related concepts:
  - Tree diameter (longest path)
  - Tree centroid (decomposition)
  - Tree center (this problem!)

Key theorem:
  "A tree has at most 2 centers"

  Proof sketch:
    If 3+ centers existed:
      They'd form a path
      Middle one is closer to periphery
      Contradiction!

  So: 1 or 2 centers only! ๐ŸŽฏ

This problem teaches:
  โœ… Tree properties
  โœ… Center finding algorithm
  โœ… BFS variation (leaf removal)
  โœ… Topological sort extension

Beautiful problem! ๐ŸŒŸ

๐ŸŽฏ Approach: Layer-by-Layer Leaf Removal (BFS)

The Key Insight ๐Ÿ’ก

Use layer-by-layer leaf removal to find tree centers ๐Ÿง…. Calculate degrees for all nodes ๐Ÿ“Š. Queue leaves (degree 1), special case for single node ๐Ÿƒ. Remove leaves layer by layer, update degrees, find new leaves ๐Ÿ”„. Stop when 1-2 nodes remain - these are centers! ๐ŸŽฏ Centers = MHT roots โœ…. At most 2 centers in any tree! Time: O(n) โšก, Space: O(n) ๐Ÿ“ฆ!

Elegant center-finding algorithm! โœจ

Complete Implementation

class Solution {
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // LAYER-BY-LAYER LEAF REMOVAL (BFS) ๐Ÿง…
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // Peel leaves until reaching center(s)
        // Centers = MHT roots!
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // EDGE CASE: Single node ๐ŸŒฑ
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        if (n == 1) {
            return Collections.singletonList(0);
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // BUILD ADJACENCY LIST ๐Ÿ—๏ธ
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // TRACK DEGREES (undirected graph) ๐Ÿ“Š
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        int[] degree = new int[n];

        // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        // Add edges (undirected - both directions)
        // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        for (int[] edge : edges) {
            int u = edge[0];
            int v = edge[1];
            graph.get(u).add(v);
            graph.get(v).add(u);
            degree[u]++;
            degree[v]++;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // FIND INITIAL LEAVES ๐Ÿƒ
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // Leaves = nodes with degree 1
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        Queue<Integer> leaves = new LinkedList<>();

        for (int i = 0; i < n; i++) {
            if (degree[i] == 1) {
                leaves.offer(i);
            }
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PEEL LEAVES LAYER BY LAYER ๐Ÿง…
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        int remainingNodes = n;

        while (remainingNodes > 2) {
            int leavesCount = leaves.size();
            remainingNodes -= leavesCount;

            // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
            // PROCESS CURRENT LAYER OF LEAVES ๐Ÿ‚
            // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
            for (int i = 0; i < leavesCount; i++) {
                int leaf = leaves.poll();

                // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                // UPDATE NEIGHBORS' DEGREES ๐Ÿ“‰
                // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                for (int neighbor : graph.get(leaf)) {
                    degree[neighbor]--;

                    // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                    // CHECK IF NEIGHBOR BECAME A LEAF ๐Ÿƒ
                    // โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                    if (degree[neighbor] == 1) {
                        leaves.offer(neighbor);
                    }
                }
            }
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // REMAINING 1-2 NODES ARE CENTERS! ๐ŸŽฏ
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        return new ArrayList<>(leaves);
    }
}

Why This Works ๐ŸŽฏ

Leaves are farthest from center: ๐Ÿƒ - Degree 1 nodes are on periphery - Removing them moves inward - Layer-by-layer approach!

Centers minimize maximum distance: ๐Ÿ“ - After removing all layers - Only 1-2 nodes remain - These are equidistant from all periphery!

At most 2 centers: ๐Ÿ”ข - Theorem: Trees have 1 or 2 centers - Our algorithm finds them all - Return as list of MHT roots!

Using Set for efficiency: โšก - Set.remove() is O(1) - Easy to check degree (size()) - Clean neighbor management!


๐Ÿ” Detailed Dry Run

Let's trace the algorithm on Example 2:

n = 6
edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                            SETUP                             โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Build adjacency list from edges:
  Edge [3,0]: 3โ†”0
  Edge [3,1]: 3โ†”1
  Edge [3,2]: 3โ†”2
  Edge [3,4]: 3โ†”4
  Edge [5,4]: 5โ†”4

Adjacency list (using Sets):
  0: {3}
  1: {3}
  2: {3}
  3: {0, 1, 2, 4}
  4: {3, 5}
  5: {4}

Tree visualization:
    0   1   2
     \ | /
      \|/
       3---4---5

Degrees:
  Node 0: degree 1 (leaf) ๐Ÿƒ
  Node 1: degree 1 (leaf) ๐Ÿƒ
  Node 2: degree 1 (leaf) ๐Ÿƒ
  Node 3: degree 4
  Node 4: degree 2
  Node 5: degree 1 (leaf) ๐Ÿƒ

Layer-by-Layer Removal ๐Ÿง…

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ ๐Ÿ” INITIALIZATION                               โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘ Build adjacency list and track degrees:        โ•‘
โ•‘                                                 โ•‘
โ•‘ graph:                                          โ•‘
โ•‘   0: [3]                                        โ•‘
โ•‘   1: [3]                                        โ•‘
โ•‘   2: [3]                                        โ•‘
โ•‘   3: [0, 1, 2, 4]                              โ•‘
โ•‘   4: [3, 5]                                     โ•‘
โ•‘   5: [4]                                        โ•‘
โ•‘                                                 โ•‘
โ•‘ degree: [1, 1, 1, 4, 2, 1]                     โ•‘
โ•‘                                                 โ•‘
โ•‘ Find initial leaves (degree 1):                โ•‘
โ•‘   Node 0: degree 1 โœ… Add to queue             โ•‘
โ•‘   Node 1: degree 1 โœ… Add to queue             โ•‘
โ•‘   Node 2: degree 1 โœ… Add to queue             โ•‘
โ•‘   Node 3: degree 4 โŒ                          โ•‘
โ•‘   Node 4: degree 2 โŒ                          โ•‘
โ•‘   Node 5: degree 1 โœ… Add to queue             โ•‘
โ•‘                                                 โ•‘
โ•‘ leaves = [0, 1, 2, 5]                          โ•‘
โ•‘ remainingNodes = 6                              โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ ๐Ÿง… ROUND 1: Remove first layer of leaves       โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘ Check: remainingNodes > 2? (6 > 2) YES        โ•‘
โ•‘                                                 โ•‘
โ•‘ Current leaves: [0, 1, 2, 5]                   โ•‘
โ•‘ leavesCount = 4                                 โ•‘
โ•‘ remainingNodes = 6 - 4 = 2                     โ•‘
โ•‘                                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘ Process leaf 0:                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘   Neighbors: [3]                                โ•‘
โ•‘   Update degree[3]: 4 โ†’ 3                      โ•‘
โ•‘   Is degree[3] == 1? NO                        โ•‘
โ•‘                                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘ Process leaf 1:                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘   Neighbors: [3]                                โ•‘
โ•‘   Update degree[3]: 3 โ†’ 2                      โ•‘
โ•‘   Is degree[3] == 1? NO                        โ•‘
โ•‘                                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘ Process leaf 2:                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘   Neighbors: [3]                                โ•‘
โ•‘   Update degree[3]: 2 โ†’ 1 โœ… NOW A LEAF!      โ•‘
โ•‘   Add 3 to queue                                โ•‘
โ•‘                                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘ Process leaf 5:                                 โ•‘
โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘
โ•‘   Neighbors: [4]                                โ•‘
โ•‘   Update degree[4]: 2 โ†’ 1 โœ… NOW A LEAF!      โ•‘
โ•‘   Add 4 to queue                                โ•‘
โ•‘                                                 โ•‘
โ•‘ After Round 1:                                  โ•‘
โ•‘   leaves = [3, 4]                              โ•‘
โ•‘   remainingNodes = 2                            โ•‘
โ•‘   degree: [-, -, -, 1, 1, -]                   โ•‘
โ•‘                                                 โ•‘
โ•‘ Tree after removing outer layer:                โ•‘
โ•‘       3---4                                     โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ ๐ŸŽฏ TERMINATION CHECK                           โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘ Check: remainingNodes > 2?                     โ•‘
โ•‘   remainingNodes = 2                            โ•‘
โ•‘   2 > 2? NO โœ…                                 โ•‘
โ•‘                                                 โ•‘
โ•‘ STOP! Centers found! ๐ŸŽฏ                        โ•‘
โ•‘                                                 โ•‘
โ•‘ leaves = [3, 4]                                โ•‘
โ•‘ These are the tree centers!                     โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

FINAL RESULT ๐ŸŽ‰

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘         ๐ŸŽ‰ FINAL RESULT: [3, 4]               โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                               โ•‘
โ•‘  Tree centers found: nodes 3 and 4! ๐ŸŽฏ        โ•‘
โ•‘                                               โ•‘
โ•‘  Verification - Height from each root:        โ•‘
โ•‘                                               โ•‘
โ•‘  Root at 3:                                   โ•‘
โ•‘      0   1   2                                โ•‘
โ•‘       \ | /                                   โ•‘
โ•‘        \|/                                    โ•‘
โ•‘         3---4---5                             โ•‘
โ•‘                                               โ•‘
โ•‘    Max depth: 2 (3โ†’4โ†’5 or 3โ†’0) โœ…            โ•‘
โ•‘                                               โ•‘
โ•‘  Root at 4:                                   โ•‘
โ•‘         4                                     โ•‘
โ•‘        / \                                    โ•‘
โ•‘       3   5                                   โ•‘
โ•‘      /|\                                      โ•‘
โ•‘     0 1 2                                     โ•‘
โ•‘                                               โ•‘
โ•‘    Max depth: 2 (4โ†’3โ†’0) โœ…                   โ•‘
โ•‘                                               โ•‘
โ•‘  Both give height 2 - minimum possible! ๐Ÿ†    โ•‘
โ•‘                                               โ•‘
โ•‘  Other roots would have height > 2:           โ•‘
โ•‘    Root 0: height 3                           โ•‘
โ•‘    Root 1: height 3                           โ•‘
โ•‘    Root 2: height 3                           โ•‘
โ•‘    Root 5: height 3                           โ•‘
โ•‘                                               โ•‘
โ•‘  MHT roots: [3, 4] โœ…                         โ•‘
โ•‘                                               โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

๐Ÿ”‘ Key Observations:

  1. Degree array tracks connectivity: ๐Ÿ“Š Each node's degree updated as leaves removed

  2. Two centers found: ๐Ÿ”ข Nodes 3 and 4 both minimize height

  3. Stopping condition: ๐ŸŽฏ Stopped when 2 nodes remained

  4. Degree decrements efficiently: โšก No need to mutate graph, just track degrees

  5. Consistent with topological sort: โœ… Same pattern as Course Schedule problems!


๐Ÿ“Š Complexity Analysis

Time Complexity: O(n) โšก

Where:
  n = number of nodes

Analysis:

Build graph: O(n)
  - n-1 edges in tree
  - Each edge processed twice (undirected)
  - O(n) total

Find initial leaves: O(n)
  - Check degree of each node once

Layer-by-layer removal: O(n)
  - Each node processed at most once
  - Each edge removed at most once
  - Total: O(n + edges) = O(n) for tree

Overall: O(n) + O(n) + O(n) = O(n) โšก

Key insight:
  Each node visited once
  Each edge removed once
  Linear time! ๐Ÿš€

Example: 20,000 nodes
  Time: ~20,000 operations
  vs O(nยฒ) brute force: 400,000,000!
  20,000x faster! ๐ŸŒŸ

Space Complexity: O(n) ๐Ÿ“ฆ

Space usage:

1. Adjacency list: O(n) ๐Ÿ—๏ธ
   - n sets (one per node)
   - Total n-1 edges
   - Each edge stored twice
   - O(n) total

2. Queue: O(n) ๐ŸŒŠ
   - Worst case: all leaves in queue
   - In practice: much smaller
   - O(n) worst case

3. Result list: O(1) โœจ
   - At most 2 centers
   - Constant space

Total: O(n) + O(n) + O(1) = O(n) ๐Ÿ“ฆ

The O(n) is necessary:
  Must store graph structure
  Tree with n nodes has n-1 edges

Example: 20,000 nodes
  Graph: ~40,000 entries (edges ร— 2)
  Queue: up to 20,000
  Reasonable space! โœ…

Core Pattern: Tree Center Finding ๐ŸŽฏ

// Template for tree center finding
class Solution {
    public List<Integer> findTreeCenters(int n, int[][] edges) {
        // Edge case: single node
        if (n == 1) return Collections.singletonList(0);

        // Build adjacency list (undirected)
        List<Set<Integer>> graph = buildGraph(n, edges);

        // Find initial leaves (degree 1)
        Queue<Integer> leaves = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            if (graph.get(i).size() == 1) {
                leaves.offer(i);
            }
        }

        // Remove leaves layer by layer
        int remaining = n;
        while (remaining > 2) {
            int size = leaves.size();
            remaining -= size;

            for (int i = 0; i < size; i++) {
                int leaf = leaves.poll();
                int neighbor = graph.get(leaf).iterator().next();
                graph.get(neighbor).remove(leaf);

                if (graph.get(neighbor).size() == 1) {
                    leaves.offer(neighbor);
                }
            }
        }

        // Remaining nodes are centers
        return new ArrayList<>(leaves);
    }
}

When to Use This Pattern ๐ŸŽฏ

โœ… Undirected tree structure
โœ… Find central node(s)
โœ… Minimize some distance/height property
โœ… Layer-by-layer processing from periphery
โœ… At most 2 solutions expected

Recognition triggers: ๐Ÿ” - "Minimum height" in trees ๐ŸŒณ - "Find center(s)" ๐ŸŽฏ - Undirected tree given ๐Ÿ”„ - Optimize root selection ๐Ÿ“ - Layer removal approach ๐Ÿง…

Key insight: Peel from outside to find center! ๐Ÿ’ก

Direct Applications:

  1. Tree Diameter (LC 1245) - Medium ๐Ÿ“ โ€ข What's similar: Tree structure, center-related ๐ŸŒณ โ€ข What's different: Find longest path, not centers ๐ŸŽฏ โ€ข Key insight: Two BFS or center-based approach! ๐Ÿ’ก

  2. Sum of Distances in Tree (LC 834) - Hard ๐Ÿ“Š โ€ข What's similar: Tree structure, all roots considered ๐ŸŒณ โ€ข What's different: Calculate sums for all roots efficiently ๐Ÿ“ˆ โ€ข Key insight: Rerooting technique! โšก

  3. Longest Path in DAG (various) - Medium/Hard ๐ŸŽฏ โ€ข What's similar: Find extremes in graph structure ๐Ÿ“ โ€ข What's different: Directed graph, different goal ๐Ÿ”„ โ€ข Key insight: Topological sort + DP! ๐ŸŒŸ

Pattern Evolution: ๐Ÿ“ˆ

Level 1: Tree Center Finding ๐ŸŽฏ โ† HERE
  โ””โ”€ Minimum Height Trees (LC 310)

Level 2: Tree Properties ๐ŸŒณ
  โ”œโ”€ Tree Diameter (LC 1245)
  โ”œโ”€ Height of Binary Tree (LC 104)
  โ””โ”€ Maximum Depth (various)

Level 3: Tree Rerooting ๐Ÿ”„
  โ”œโ”€ Sum of Distances in Tree (LC 834)
  โ”œโ”€ Count Good Nodes (LC 1339)
  โ””โ”€ Tree DP (various)

Comparison with Kahn's Algorithm โš–๏ธ

Kahn's Algorithm (Topological Sort):
  - Directed graph
  - Remove nodes with in-degree 0
  - Process all nodes
  - Result: topological ordering

MHT (Tree Centers):
  - Undirected tree
  - Remove nodes with degree 1 (leaves)
  - Stop at 1-2 nodes
  - Result: center node(s)

Similarities:
  โœ… Layer-by-layer BFS
  โœ… Queue-based processing
  โœ… Degree tracking
  โœ… Remove and update pattern

Differences:
  โŒ Directed vs undirected
  โŒ In-degree vs degree
  โŒ Process all vs stop early
  โŒ Ordering vs center finding

Same pattern family, different application! ๐ŸŽฏ

๐Ÿ“ Quick Revision Notes

๐ŸŽฏ Core Concept

Minimum Height Trees finds tree centers using layer-by-layer leaf removal ๐Ÿง…. Build adjacency list (undirected), find leaves (degree 1) ๐Ÿƒ. Remove leaves layer by layer, update degrees, find new leaves ๐Ÿ”„. Stop when 1-2 nodes remain - these are centers = MHT roots! ๐ŸŽฏ Tree has at most 2 centers (theorem) โœ…. Similar to Kahn's but undirected tree + stop early ๐Ÿ”„. Time: O(n) โšก, Space: O(n) ๐Ÿ“ฆ. Peel from outside to center!

โšก Quick Implementation

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
  public List<Integer> findMinHeightTrees(int n, int[][] edges) {
    // Approach - BFS
    return bfs(n, edges);
  }

  private List<Integer> bfs(int n, int[][] edges) {
    // base case
    if (n == 1) {
      return Collections.singletonList(0);
    }

    // Step 1: create graph and indegrees array.
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    int[] indegrees = new int[n];

    for (int i = 0; i < n; i++) {
      graph.add(new ArrayList<>());
    }

    // GOTCHA: same as before, but 2 times insert now as its undirected graph now.
    for (int i = 0; i < edges.length; i++) {
      graph.get(edges[i][0]).add(edges[i][1]);
      graph.get(edges[i][1]).add(edges[i][0]);
      indegrees[edges[i][0]]++;
      indegrees[edges[i][1]]++;
    }

    // Step 2: find vertices which are leaf nodes (like indegrees with 1 value)
    Queue<Integer> queue = new LinkedList<>();
    for (int i = 0; i < n; i++) {
      if (indegrees[i] == 1) {
        queue.offer(i);
      }
    }

    // Step 3: Explore till n <= 2. Checking quue empty is optional.
    // Main logic: n > 2
    while (!queue.isEmpty() && n > 2) {
      // Explore all leaf nodes
      int size = queue.size();
      n = n - size; // GOTCHA: reduce the number of nodes to explore

      for (int i = 0; i < size; i++) {
        int node = queue.poll();

        for (int neighbour : graph.get(node)) {
          indegrees[neighbour]--;

          if (indegrees[neighbour] == 1) { // leaf node
            queue.offer(neighbour);
          }
        }
      }
    }

    return new ArrayList<>(queue);
  }

  public static void main(String[] args) {
    Solution s = new Solution();
    System.out.println(s.findMinHeightTrees(4, new int[][] { { 1, 0 }, { 1, 2 }, { 1, 3 } }));
    System.out.println(s.findMinHeightTrees(6, new int[][] { { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 4 }, { 5, 4 } }));
  }
}

๐Ÿ”‘ Key Insights

Why Centers Minimize Height: ๐Ÿ“

Geometric intuition:

Linear chain: 0---1---2---3---4

Root at 0 (edge):
  Max distance: 0โ†’4 = 4
  Height = 4

Root at 2 (center):
  Max distance: 2โ†’0 or 2โ†’4 = 2
  Height = 2 โœ… MINIMUM!

Key insight:
  Center = equidistant from extremes
  Minimizes maximum distance
  = Minimizes tree height! ๐ŸŽฏ

For any tree:
  Best root is at center
  Center minimizes "worst case" distance
  Perfect for minimizing height! โœจ

At Most 2 Centers Theorem: ๐Ÿ”ข

Theorem: Every tree has 1 or 2 centers.

Proof by contradiction:
  Assume 3+ centers exist: A, B, C

  Centers are equidistant from periphery:
    distance(A, periphery) = d
    distance(B, periphery) = d
    distance(C, periphery) = d

  A, B, C must form a path in tree:
    A---B---C

  But then B is closer to periphery than A or C!
    (By triangle inequality)

  Contradiction! โŒ

Therefore: At most 2 centers! โœ…

In practice:
  Odd-length diameter: 1 center
  Even-length diameter: 2 centers

Using Degree Array: ๐Ÿ’ก

Why track degrees explicitly?

For leaf removal:
  Need to: check if node is a leaf (degree 1)
  Need to: update degrees when removing edges

With Set (old approach):
  graph.get(node).size() gives degree
  Must remove edges: set.remove(neighbor)

With degree array (new approach):
  degree[node] gives degree directly
  Just decrement: degree[neighbor]--
  Simpler and more consistent! โœ…

Advantages:
  โœ… Consistent with topological sort problems
  โœ… No need to remove edges from graph
  โœ… Cleaner degree tracking
  โœ… Same pattern as Course Schedule I/II

Example:
  Initial: degree = [1, 3, 2, 1]

  Process leaf 0, neighbor 1:
    degree[1]-- โ†’ 2

  Process leaf 3, neighbor 1:
    degree[1]-- โ†’ 1 (now a leaf!)

Track degrees, don't mutate graph! ๐ŸŽฏ

Stop at 1-2 Nodes: ๐ŸŽฏ

Why stop when remaining > 2?

while (remaining > 2) {
  // Remove layer
}

After loop:
  remaining = 1 or 2

These are the centers!

Why not remaining > 1?
  Would remove one of the two centers!

Why not remaining > 0?
  Would try to remove all nodes!

remaining > 2 is perfect:
  Stops at 1 node (odd diameter)
  OR stops at 2 nodes (even diameter)

These are exactly the centers! ๐ŸŽฏ

Layer-by-Layer Processing: ๐Ÿง…

Key pattern: Process entire layer at once!

int size = leaves.size();  // Current layer size
remaining -= size;          // Remove entire layer

for (int i = 0; i < size; i++) {
  // Process leaf
  // Find new leaves
}

Why process by layers?
  Ensures we move inward uniformly
  All leaves at same "distance" from center
  Clean peeling pattern! ๐Ÿง…

Like BFS levels:
  Level 0: Outer leaves
  Level 1: Next leaves
  ...
  Final level: Center(s)! ๐ŸŽฏ

๐ŸŽช Memory Aid

"Peel the onion layer by layer" ๐Ÿง…
"Leaves removed, centers stay" ๐Ÿƒ
"One or two nodes at most" ๐Ÿ”ข
"These are centers, found at last" ๐ŸŽฏ โœจ

โš ๏ธ Don't Forget

  • Single node edge case - return [0] immediately! ๐ŸŒฑ
  • Use Set for graph - faster removal operations! โšก
  • Stop at 1-2 nodes - not 0 or 1! ๐Ÿ”ข
  • Process entire layer - track layer size! ๐Ÿง…
  • Undirected edges - add both directions! ๐Ÿ”„
  • At most 2 centers - tree property! ๐Ÿ“

You've mastered Minimum Height Trees - tree center finding with leaf removal! ๐ŸŒŸ๐ŸŒณโœจ