Skip to content
ΣDSA Patterns
Menu
Language

Topological Sort

Guide 4 of 6 · Path 4 of 6

Interactive

Mental model

A worked animation for this problem. Scrub steps or press space to pause; re-tell the invariant out loud.

Step 1 of 6
1deg 30leaf2leaf3leaf

peel degree-1 layers

Minimum height trees: undirected tree, n=4, star at 1. Roots that minimize height are the centroid(s) — always 1 or 2 nodes.

Demo preview: These solutions pass the automated test suite but have not been human-reviewed. Treat trade-offs and prose as draft.

Minimum Height Trees

Problem (restated)

Undirected tree with n nodes. Return all roots that minimize the height of the rooted tree (1 or 2 centroids).

Intuition

Repeatedly remove leaves (degree 1). Last remaining 1-2 nodes are the centers / MHT roots.

Approaches

Peel leaves to centroids

Unverified
Time O(n)Space O(n)

Idea. Kahn-style layer peel until ≤2 nodes left.

Walkthrough. n=4, edges=[[1,0],[1,2],[1,3]] → [1].

Trade-offs. Diameter midpoints give the same answer; leaf peel is simpler to code.

Solution
export function findMinHeightTrees(n: number, edges: number[][]): number[] {
  if (n === 1) return [0];
  const g: number[][] = Array.from({ length: n }, () => []);
  const deg = Array(n).fill(0);
  for (const e of edges) {
    g[e[0]!]!.push(e[1]!);
    g[e[1]!]!.push(e[0]!);
    deg[e[0]!]!++;
    deg[e[1]!]!++;
  }
  let q: number[] = [];
  for (let i = 0; i < n; i++) if (deg[i] === 1) q.push(i);
  let remain = n;
  while (remain > 2) {
    const next: number[] = [];
    remain -= q.length;
    for (const u of q) {
      for (const v of g[u]!) {
        if (--deg[v]! === 1) next.push(v);
      }
    }
    q = next;
  }
  return q;
}
export function findMinHeightTrees(n: number, edges: number[][]): number[] {
  if (n === 1) return [0];
  const g: number[][] = Array.from({ length: n }, () => []);
  const deg = Array(n).fill(0);
  for (const e of edges) {
    g[e[0]!]!.push(e[1]!);
    g[e[1]!]!.push(e[0]!);
    deg[e[0]!]!++;
    deg[e[1]!]!++;
  }
  let q: number[] = [];
  for (let i = 0; i < n; i++) if (deg[i] === 1) q.push(i);
  let remain = n;
  while (remain > 2) {
    const next: number[] = [];
    remain -= q.length;
    for (const u of q) {
      for (const v of g[u]!) {
        if (--deg[v]! === 1) next.push(v);
      }
    }
    q = next;
  }
  return q;
}

Template connection

Layered leaf removal (topo-like on trees).

Reflection