Minimum Height Trees

medium

A tree is an undirected graph in which any two vertices are connected by exactly one path. Given a tree of n nodes labelled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [aᵢ, bᵢ] indicates an undirected edge between nodes aᵢ and bᵢ, you can choose any node of the tree as the root.

When you pick 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 the root labels of the minimum height trees. 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.

How your function is called

findMinHeightTrees(n, edges)  ->  list of root labels

The input is fed as: the number of nodes n, then the number of edges m, then m lines each holding one edge a b.

Hints

Think about which nodes are clearly bad roots. Where in a tree would you never place the center?
A leaf (a node with only one neighbour) is always a bad root — there is always a longer path going inward through its single neighbour. What if you removed all leaves at once?
Build a degree array (neighbour count per node) and a queue of all degree-1 nodes. When you "remove" a leaf, what happens to its neighbour's degree?
This is topological-sort style, but on an undirected tree. Trim leaves in whole layers (not one at a time) until 2 or fewer nodes remain — those are your answer.

Common doubts

A tree has exactly one path between any two nodes, so its longest path (the diameter) is unique. The center of a unique path is either 1 node (odd length) or 2 nodes (even length). Three centers would require two separate diameters — impossible in a tree.
Because the answer can be 1 or 2 nodes. Stopping at 1 could delete one of the two valid centers. Stopping at remaining <= 2 captures both cases.
A single node has no edges, so there are no leaves to trim and the loop never runs. Handle it up front and return [0].

Interview follow-ups

Leaf-trimming relies on the tree property. With cycles you would need cycle handling; the problem guarantees a tree, but acknowledging this shows depth.
Count the trimming rounds. Each round peels one layer, so the final height equals the number of rounds.
Leaf-trimming counts hops, not weights. For weights, fall back to two BFS/DFS passes to find the weighted diameter, then walk to its center.

Fun facts

  • The leaf-trimming technique here is essentially Kahn's algorithm for topological sort — applied to an undirected tree instead of a DAG. You are learning two algorithms at once.
  • That every tree has at most two centers is a classical graph-theory theorem, proven in the 19th century — long before competitive programming existed.
  • Placing a server or warehouse at the center of a network minimises worst-case latency. This problem is the graph version of "find the middle of a linked list".

Asked at

AmazonGoogleMetaMicrosoft
Frequently Sometimes Occasionally
Example 1
Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Rooting the tree at node 1 gives height 1 — the minimum. Every other root gives height 2.
Example 2
Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
Output: [3,4]
Both node 3 and node 4 give a tree of height 2 — the minimum. They are the two centers of the tree.
Example 3
Input: n = 1, edges = []
Output: [0]
A single node is trivially its own minimum height tree.
Constraints

- 1 <= n <= 2 * 10^4 - edges.length == n - 1 - 0 <= a_i, b_i < n - a_i != b_i - The given input is guaranteed to be a tree (connected, acyclic).

Solve this problem →