• 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 };
  • 相关阅读:
    简单dp总结
    一、极限总结
    最短路径之差分约束
    软工个人总结
    BETA事后总结
    BETA(7)
    BETA(6)
    BETA(5)
    Go 中的字符串相关操作
    Go 中的异常/错误处理
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14468580.html
Copyright © 2020-2023  润新知