题目来源
题目描述
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
}
};
题目解析
直觉上,一棵树越靠「外面」的结点,我们越不可能把它作为根结点
思路:一层一层的褪去叶节点,最后剩下的一个或两个节点就是我们要求的最小高度树的根节点
算法:
- 先建立一个连接图,保存了i节点可以到达的所有节点。
- 然后将所有只有一个连接边(叶子节点)都存入一个queue中
- 然后遍历queue,找到和叶子节点相连的节点,并在这些节点中将这个叶子节点删除,如果删除之后也变为叶子节点了,就加入队列,进行下一轮删除
- 什么时候删除停止呢?当queue只有一个/两个节点时
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int> >& edges) {
if (n == 1) return {0};
vector<int> res;
vector<unordered_set<int>> adj(n);
queue<int> q;
for (auto edge : edges) {
adj[edge.first].insert(edge.second);
adj[edge.second].insert(edge.first);
}
for (int i = 0; i < n; ++i) {
if (adj[i].size() == 1) q.push(i);
}
while (n > 2) {
int size = q.size();
n -= size;
for (int i = 0; i < size; ++i) {
int t = q.front(); q.pop();
for (auto a : adj[t]) {
adj[a].erase(t);
if (adj[a].size() == 1) q.push(a);
}
}
}
while (!q.empty()) {
res.push_back(q.front()); q.pop();
}
return res;
}
};