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 = 4edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3

return [1]

Example 2:

Given n = 6edges = [[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 }

 

posted @ 2016-08-09 09:17  北叶青藤  阅读(212)  评论(0编辑  收藏  举报