Skip to content

310 Minimum Height Trees

Approach 1 BFS

This solution is illustrated in the following diagram:

We start from all leaves nodes, and spirally converge to the center of the tree. At the end, the last two nodes are the root of the tree that give the minimum height.

Note

The stop condition is when the number of nodes is less than or equal to 2. You can think of it as finding the median of odd and even length of the array.

Code Implementation

class Solution:
    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        """
        BFS Solution:
        n = 4, edges = [[1,0],[1,2],[1,3]]
        1. build adjacency list
        {
            0:[1],
            1:[0,2,3],
            2:[1],
            3:[1],
        }
        2. count edge
        {
            0:1,
            1:3,
            2:1,
            3:1,
        }
        3. maintain a queue that stores leaf node (where edge == 1)
        4. iterating until the queue's length is less than 2,
        conducting BFS, we poping the leaf node, reduce the associated
        nodes (by adj list), then reduce the edge count by 1.
        Note:
        - One edge case is that: when n = 1, there is no edges. Since node starting from n-1,
        so we return [0].
        """
        if n == 1:
            return [0]

        adj_list = defaultdict(list)
        for a,b in edges:
            adj_list[a].append(b)
            adj_list[b].append(a)

        edge_count = {}
        leaves = collections.deque()
        for node,neighbors in adj_list.items():
            edge_count[node] = len(neighbors)
            if len(neighbors) == 1:
                leaves.append(node)

        while leaves:
            # base case
            if n <= 2:
                return list(leaves)
            for i in range(len(leaves)):
                node = leaves.popleft()
                n -= 1
                for neighbor in adj_list[node]:
                    edge_count[neighbor] -= 1
                    if edge_count[neighbor] == 1:
                        leaves.append(neighbor)