310. 最小高度树
一、题目
1.题目描述
树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
给你一棵包含 n
个节点的树,标记为 0
到 n - 1
。给定数字 n
和一个有 n - 1
条无向边的 edges
列表(每一个边都是一对标签),其中 edges[i] = [ai, bi]
表示树中节点 ai
和 bi
之间存在一条无向边。
可选择树中任何一个节点作为根。当选择节点 x
作为根节点时,设结果树的高度为 h
。在所有可能的树中,具有最小高度的树(即,min(h)
)被称为 最小高度树 。
请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。
树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。
示例 1:
输入:n = 4, edges = [[1,0],[1,2],[1,3]]
输出:[1]
解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。
示例 2:
输入:n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
输出:[3,4]
提示:
1 <= n <= 2 * 10^4
edges.length == n - 1
0 <= ai, bi < n
ai != bi
- 所有
(ai, bi)
互不相同 - 给定的输入 保证 是一棵树,并且 不会有重复的边
2.基础框架
C++基础框架代码如下:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
}
3.解题思路
- 题目分析
-
题目目标返回所有最小高度树的根节点。
-
树的高度定义:根节点和叶子结点之间的最长路径 边的数量。
-
最小高度树就是 最长的路径的中点作为根节点的树。
-
最长路径可以通过BFS求得。
-
如果最长路径长度为奇数,则最小高度树的根节点只有一个,如果为偶数,则最小高度树的根节点有两个。
-
实现代码:
#define N 20005 vector<int> Edge[N]; int pre[N]; int dist[N]; class Solution { public: void add_Edge(int u, int v) { Edge[u].push_back(v); Edge[v].push_back(u); return ; } void init(int n, vector<vector<int> >& edges) { for (int i = 0; i < n; i++) Edge[i].clear(); return ; } int bfs(int u, int n) { memset(dist, -1, sizeof(dist)); queue<int> que; que.push(u); dist[u] = 0; pre[u] = -1; while (!que.empty()) { int u = que.front(); que.pop(); for (int i = 0; i < Edge[u].size(); i++) { int v = Edge[u][i]; if (dist[v] == -1) { dist[v] = dist[u] + 1; pre[v] = u; que.push(v); } } } int max1 = 0; for (int i = 1; i < n; i++) { if (dist[i] > dist[max1]) max1 = i; } return max1; } vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { if (n == 1) return {0}; init(n, edges); for (int i = 0; i < edges.size(); i++) { add_Edge(edges[i][0], edges[i][1]); } int x = bfs(edges[0][0], n); int y = bfs(x, n); // cout << x << " " << y << endl; vector<int> path; path.clear(); while (x != y) { path.push_back(y); y = pre[y]; } path.push_back(x); // for (auto i : path) // cout << i << endl; if (path.size() & 1) return {path[(path.size() - 1) / 2]}; else return {path[(path.size() - 1) / 2], path[path.size() / 2]}; } };
二、参考资料
https://blog.csdn.net/WhereIsHeroFrom/article/details/124004342