Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n
nodes which are labeled from 0
to n - 1
. You will be given the number n
and a list of undirected edges
(each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
Example 1:
Given n = 4
, edges = [[1, 0], [1, 2], [1, 3]]
0 | 1 / \ 2 3
return [1]
Example 2:
Given n = 6
, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 \ | / 3 | 4 | 5
return [3, 4]
分析:
首先笨办法,假设每个点都是root, 然后利用BFS,看那个root到最后一个leaf的高度是多少,如果比目前找到的更小,则更新,如果相同,则把那个点加到list里。
1 public List<Integer> findMinHeightTrees(int n, int[][] edges) { 2 List<Integer> all = new ArrayList<Integer>(); 3 if (n <= 1) { 4 all.add(0); 5 return all; 6 } 7 8 Map<Integer, List<Integer>> map = new HashMap<>(); 9 10 for (int i = 0; i < n; i++) { 11 map.put(i, new ArrayList<Integer>()); 12 } 13 14 for (int[] edge : edges) { 15 map.get(edge[1]).add(edge[0]); 16 map.get(edge[0]).add(edge[1]); 17 } 18 19 int minHeight = Integer.MAX_VALUE; 20 List<Integer> temp = new ArrayList<>(); 21 for (int i = 0; i < n; i++) { 22 int height = 0; 23 boolean[] visited = new boolean[n]; 24 visited[i] = true; 25 List<Integer> list = map.get(i); 26 while (list.size() != 0) { 27 for (Integer k : list) { 28 if (!visited[k]) { 29 visited[k] = true; 30 temp.addAll(map.get(k)); 31 } 32 } 33 list = temp; 34 temp = new ArrayList<>(); 35 height++; 36 } 37 if (height < minHeight) { 38 all.clear(); 39 all.add(i); 40 minHeight = height; 41 } else if (height == minHeight) { 42 all.add(i); 43 } 44 } 45 return all; 46 }
更好的方法,先构成一棵树,把数的叶子逐层的砍掉(叶子的degree为1),当这棵树只剩下2颗或者不到两颗的节点的时候,就停止。
1 public class Solution { 2 public List<Integer> findMinHeightTrees(int n, int[][] edges) { 3 List<Integer> leaves = new ArrayList<Integer>(); 4 if (n <= 1) { 5 leaves.add(0); 6 return leaves; 7 } 8 9 List<Set<Integer>> graph = new ArrayList<>(); 10 11 for (int i = 0; i < n; i++) { 12 graph.add(new HashSet<Integer>()); 13 } 14 15 for (int[] edge : edges) { 16 graph.get(edge[1]).add(edge[0]); 17 graph.get(edge[0]).add(edge[1]); 18 } 19 20 for (int i = 0; i < n; i++) { 21 if (graph.get(i).size() == 1) { 22 leaves.add(i); 23 } 24 } 25 26 while (n > 2) { 27 n -= leaves.size(); 28 List<Integer> newLeaves = new ArrayList<>(); 29 for (int leave : leaves) { 30 for (int newLeaf : graph.get(leave)) { 31 graph.get(newLeaf).remove(leave); 32 if (graph.get(newLeaf).size() == 1) { 33 newLeaves.add(newLeaf); 34 } 35 } 36 } 37 leaves = newLeaves; 38 } 39 40 return leaves; 41 } 42 }