题目描述
解法:拓扑排序
最简单的方法是对每个顶点都做一遍 bfs,记录下每个结点的高度,再取最小即可。想法没问题,超时
我们还是沿着 bfs 的思路再想一下,其实我们有一个直觉,最小树的根节点一定是图中最长路径的中间节点,这一点是可以通过数学证明的,详细可以参见 官方题解
那么,接下来我们就可以根据拓扑排序来确定最长路径上能形成最小数的根节点,如下所示
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
if (n==1) return {0};
vector<int> degree(n);
vector<vector<int>> adj(n);
for (auto e: edges)
{
adj[e[0]].emplace_back(e[1]);
adj[e[1]].emplace_back(e[0]);
degree[e[0]]++;
degree[e[1]]++;
}
queue<int> q;
vector<int> ans;
for (int i = 0; i < n; i++)
{
if (degree[i] == 1) q.emplace(i);
}
int remain_nodes = n;
while (remain_nodes > 2)
{
int k = q.size();
remain_nodes -= k;
for (int i = 0; i < k; i++)
{
int cur = q.front();
q.pop();
for (auto v: adj[cur])
{
degree[v]--;
if (degree[v] == 1) q.emplace(v);
}
}
}
while (!q.empty())
{
ans.emplace_back(q.front());
q.pop();
}
return ans;
}
};