310. 最小高度树

对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。

格式

该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。

你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。

示例 1:

输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]

0
|
1
/ \
2 3

输出: [1]
示例 2:

输入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

0 1 2
\ | /
3
|
4
|
5

输出: [3, 4]
说明:

 根据树的定义,树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
树的高度是指根节点和叶子节点之间最长向下路径上边的数量

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-height-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 1 //dfs 超时 
 2 class Solution {
 3 public:
 4     map<int, vector<int>> MAP;
 5     vector<int> res;
 6     int MAX_DEPTH = INT_MAX;
 7     vector<int> visited;
 8     int getDepth(int root, int depth)
 9     {
10         int max_depth = depth;
11         visited[root] = 1;
12         for (auto item : MAP[root])
13         {
14             if (!visited[item])
15             {
16                 //cout << root << " " << item << endl;
17                 max_depth = max(max_depth, getDepth(item, depth + 1));
18             }
19         }
20         return max_depth;
21     }
22     //深度遍历 求出以i为根节点的树的高度 将高度最小的放入res中
23     vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
24         visited.resize(n, 0);
25         for (auto item : edges) 
26         { 
27             MAP[item[0]].push_back(item[1]); 
28             MAP[item[1]].push_back(item[0]);
29         }
30         for (int i = 0; i < n; i++)
31         {
32             for (int k = 0; k < n; k++)visited[k] = 0;
33             int depth = getDepth(i, 0);
34             //cout << depth << endl;
35             if (depth == MAX_DEPTH)res.push_back(i);
36             else if (depth < MAX_DEPTH)
37             {
38                 MAX_DEPTH = depth;
39                 res.clear();
40                 res.push_back(i);
41             }
42         }
43         return res;
44     }
45 };
//bfs 超时
class Solution {
public:
    map<int, vector<int>> MAP;
    vector<int> res;
    int MAX_DEPTH = INT_MAX;
    vector<int> visited;
    queue<int> que;
    int bfs(int root)
    {
        que.push(root);
        int last = root;
        int level = 1;
        while (!que.empty())
        {
            int t = que.front();
            que.pop();
            if (visited[t])continue;
            visited[t] = 1;
            for (auto item : MAP[t])
                if (!visited[item])
                    que.push(item);
            if (last == t&& !que.empty())
            {
                level++;
                last = que.back();
            }
        }
        return level;
    }
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        visited.resize(n, 0);
        for (auto item : edges) 
        { 
            MAP[item[0]].push_back(item[1]); 
            MAP[item[1]].push_back(item[0]);
        }
        for (int i = 0; i < n; i++)
        {
            for (int k = 0; k < n; k++)visited[k] = 0;
            int depth = bfs(i);
            if (depth == MAX_DEPTH)res.push_back(i);
            else if (depth < MAX_DEPTH)
            {
                MAX_DEPTH = depth;
                res.clear();
                res.push_back(i);
            }
        }
        return res;
    }
};
//1、统计每个结点的度
//2、将度为1的结点删除
//3、再重复1-2步骤 直至还剩1/2个结点为止
class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        map<int, vector<int>> MAP;
        int left = n;
        vector<int> degree(n, 0);
        vector<int> left_node(n, 1);
        for (auto item : edges)
        {
            MAP[item[0]].push_back(item[1]);
            MAP[item[1]].push_back(item[0]);
        }
        for (auto item : MAP)
            degree[item.first] = item.second.size();
        vector<int> to_deletes;
        while (left > 2)
        {
            to_deletes.clear();
            for (int i = 0; i < n; i++)
                if (degree[i] == 1)
                {
                    to_deletes.push_back(i);
                    left--;
                    left_node[i] = 0;
                    degree[i]=0;
                }
            for(auto i:to_deletes)
                for(auto j:MAP[i])
                    if(left_node[j])
                        degree[j]--;
        }
        vector<int> res;
        for (int i = 0; i < n; i++)if (left_node[i])res.push_back(i);
        return res;
    }
};

 

posted @ 2020-07-28 18:55  lancelee98  阅读(207)  评论(0编辑  收藏  举报