对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。
格式
该图包含 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; } };