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]


題意: 

給一個數字n,代表了無向圖的節點總數。然後給出該圖中所有的邊。找出以某個節點爲根節點,使得樹的高度最短。

 

思路: 
最簡單的暴力的方式就是嘗試以每個節點作爲根節點,然後使用廣度優遍歷的方法去遍歷這個樹的高度。不過這樣的話時間複雜度就變成了O(n^2)。 
換一個思路。我們知道在樹中有葉子節點跟非葉子節點兩種。葉子節點的度是1,即只有一個點與葉子節點相鄰
(也或者只有一個節點的話就沒有相鄰的節點)。中間節點的度都>=2。 
另一個知識就是去找一根繩子的長度,我們可以讓兩隻螞蟻從兩端開始爬行,每次爬一步,若干步後它們相遇或者只差一步就說明找到了繩子的長度了。 
結合上面的知識,我們使用這樣的思路,讓螞蟻從各個葉子往中間爬,每次爬一步之後,丟棄上一個節點,
並且判斷此時哪些成爲了葉子節點,然後繼續爬,直到最後兩個螞蟻相遇或者差一步就是最長的一個距離了。
這兩個螞蟻的位置就是根的位置,這個樹最少要有這麼高。

public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<Integer> list=new ArrayList<Integer>();
if(n<=0)return list;
else if(edges.length<=0){
for (int i=0;i<n;i++)
list.add(i);
return list;
}
Map<Integer, ArrayList<Integer>> graph = new HashMap<Integer,ArrayList<Integer>>();  
    for(int i=0;i<n;i++) graph.put(i, new ArrayList<Integer>());  
    int[] neighbors = new int[n];  
    for(int[] edge :edges){//建立鄰接表
    neighbors[edge[0]]++;
    neighbors[edge[1]]++;
    graph.get(edge[0]).add(edge[1]);
    graph.get(edge[1]).add(edge[0]);
    }
    for(int i=0;i<n;i++)
    if(graph.get(i).size()==1)list.add(i);
    while(n>2){
    List<Integer> newList=new ArrayList<Integer>();
    for(int l :list){
    --n;
    for(int nb :graph.get(l)){
    if(--neighbors[nb]==1)newList.add(nb);
    }
    }
    list=newList;
    }
return list;
        
    }
發佈了13 篇原創文章 · 獲贊 24 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章