常规方法可以使用BFS或者DFS,对每个点都遍历一遍,求出所有点组成的树的高度,然后找出那些高度最小的节点,可以通过不断更新最低高度来进行剪枝。但是时间复杂度过高。
最终的解题思路采用了不断删除叶子节点,逐渐逼近根节点的方法,在删除叶子节点的同时,会有一些新的节点成为叶子节点,于是继续循环删除,直至不能删除为止,那么剩下的节点就是高度最小的根。
首先将图存储起来,并将每个节点的入度存储起来,然后遍历将入度为1(叶节点)的节点加入队列。
bfs,当队列不空,取队列存储过的叶子节点再将叶子节点的邻接节点,如果邻接节点的度也为1(叶子节点),加入队列。
如此反复,直到减掉所有叶子节点最后一批剩下来的就是正确答案。
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
vector<int> ans;
if(n==1){
ans.push_back(0); return ans;
}
vector<int> indegree(n,0);
vector<int> graph[n];
for(auto cur:edges){
int u=cur[0];
int v=cur[1];
graph[u].push_back(v); graph[v].push_back(u);
indegree[u]++;indegree[v]++;
}
queue<int> qu;
for(int i=0;i<n;i++){
if(indegree[i]==1) qu.push(i); //leaf
}
while(!qu.empty()){
ans.clear();
int cnt=qu.size();
for(int j=0;j<cnt;j++){
int cur=qu.front();
ans.push_back(cur); qu.pop();
for(int i=0;i<graph[cur].size();i++){
int x=graph[cur][i];
if(indegree[x]>0) {
indegree[cur]--;
indegree[x]--;
}
if(indegree[x]==1) qu.push(x);
}
}
}
return ans;
}
};