LeetCode刷题实战310:最小高度树
示例
解题
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
//处理特殊的情形
if(n==1){
return {0};
}
if(n==2){
return {0,1};
}
//建立图
vector<vector<int>> graph(n);
//统计各个结点的入度,这里是无向图,实际既相邻的结点的数量
vector<int> in_degree(n,0);
for(vector<int>& edge:edges){
graph[edge[0]].push_back(edge[1]);
graph[edge[1]].push_back(edge[0]);
++in_degree[edge[0]];
++in_degree[edge[1]];
}
queue<int> q;//队列实现广度优先搜索
//将起始的度为1的结点压入到队列中
for(int i=0;i<n;++i){
if(in_degree[i]==1){
q.push(i);
in_degree[i]=0;//标识不再访问,变相的删除结点操作
}
}
//当没有遍历的结点的数量小于等于2时,则终止循环,剩余的这1个或2个结点,即为中间结点
while(n>2){
int cur_size=q.size();//当前层要删除的结点数量
n-=cur_size;//删除结点
//逐个遍历要删除的结点,减少相邻的结点的度
while(cur_size--){
int cur_index=q.front();//当前结点
q.pop();
//遍历当前结点的相邻结点,再相邻结点没有被删除过的情形下,既度符合要求的情形下
for(int& cur_i:graph[cur_index]){
if(in_degree[cur_i]>1){//度符合要求,则可以访问
//该相邻结点的度减1
--in_degree[cur_i];
//若度等于1,则说明也是新的叶子结点,既可以删除的结点,压入到队列中,并将对应的度置为0进行标识
if(in_degree[cur_i]==1){
q.push(cur_i);
in_degree[cur_i]=0;
}
}
}
}
}
//获得结果
vector<int> res;
while(!q.empty()){
res.push_back(q.front());
q.pop();
}
return res;
}
};