310. Minimum Height Trees

问题:

求给定无向图(树),从那个顶点作为root,得到最矮树。

Example 1:
Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Explanation: As shown, the height of the tree is 1 when the root is the node with 
label 1 which is the only MHT.

Example 2:
Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
Output: [3,4]

Example 3:
Input: n = 1, edges = []
Output: [0]

Example 4:
Input: n = 2, edges = [[0,1]]
Output: [0,1]
 
Constraints:
1 <= n <= 2 * 104
edges.length == n - 1
0 <= ai, bi < n
ai != bi
All the pairs (ai, bi) are distinct.
The given input is guaranteed to be a tree and there will be no repeated edges.

  

解法:BFS

该问题,看作无向图的遍历,

从图中哪个节点开始遍历,使得到leaf节点的距离最短。

首先根据邻边关系,构建图:

  • nodemp[i]={a,b,c...}
    • 代表:i-a, i-b, i-c...

我们可有以下思路:

  1. 要找到离四周leaf节点都很近的中间节点,
  2. 那就从四周leaf节点同时向内,蚕食。
  3. 最后剩下的节点,即为到四周步数一样的解。

具体逻辑:

  • queue中首先保存所有nodemp[i].size==1的节点。(即:leaf节点)
    • ⚠️ 注意:由于最后要求的是最后一次(下一次queue为空)剩下queue里的这一层节点。
    • 因此使用tmpq,来保存处理该层queue之前queue的状态。
  • 开始遍历:
  • LOOP:
    • 处理最外层叶子节点:对于每个节点cur:
      • 删除该节点+该节点与相邻节点的连线:
      • nodemp[cur](删除,可不做,因为cur已被pop,就不再会加入queue中处理了)
        • for every nextn : nodemp[cur]
        • nodemp[nextn].erase(cur).
        • 判断是否加入queue:该邻接节点nextn也成为了叶子节点:nodemp[nextn].size==1
  • 最终返回最后一次queue的状态:tmpq->res

leetcode说明

代码参考:

 1 class Solution {
 2 public:
 3     vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
 4         vector<int> res;
 5         vector<unordered_set<int>> nodemp(n, unordered_set<int>());
 6         //vector<pair<vector<int>,unordered_set<int>>> proc(n);
 7         queue<int> q;
 8         if(n==1) return {0};
 9         for(auto ed:edges) {
10             nodemp[ed[0]].insert(ed[1]);
11             nodemp[ed[1]].insert(ed[0]);
12         }
13         for(int i=0; i<n; i++) {
14             //add all leaf node to queue
15             if(nodemp[i].size()==1) q.push(i);
16         }
17        queue<int> tmpq; 
18         while(!q.empty()) {
19             int sz = q.size();
20             tmpq = q;
21             for(int i=0; i<sz; i++) {
22                 int cur = q.front();
23                 q.pop();
24                 for(int nextn:nodemp[cur]) {
25                     //delete the leaf node(cur) with the line connected its nextn.
26                     nodemp[nextn].erase(cur);
27                     //nodemp[cur].erase(nextn);
28                     if(nodemp[nextn].size()==1) q.push(nextn);
29                 }
30             }
31         }
32         while(!tmpq.empty()) {
33             res.push_back(tmpq.front());
34             tmpq.pop();
35         }
36         return res;
37     }
38 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14468580.html