题目描述
树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一
棵树。
给你一棵包含 n 个节点的数,标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges
列表(每一个边都是一对标签),其中 edges[ i] = [ ai, bi] 表示树中节点 ai 和 bi 之间存在一条无
向边。
可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,
具有最小高度的树(即,min ( h) )被称为 最小高度树 。
请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。
树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。
题解
从边缘开始,先找到所有出度为1 的节点,然后把所有出度为1 的节点进队列,然后不断地bfs,最后找到的就是
两边同时向中间靠近的节点,那么这个中间节点就相当于把整个距离二分了,那么它就是到两边距离最小的点
,也就是到其他叶子节点最近的节点了。
代码
class Solution {
public:
vector< int > findMinHeightTrees ( int n, vector< vector< int >> & edges) {
if ( n== 1 ) return { 0 } ;
map< int , vector< int >> adj;
vector< int > degree ( n) ;
for ( int i= 0 ; i< edges. size ( ) ; i++ ) {
adj[ edges[ i] [ 0 ] ] . push_back ( edges[ i] [ 1 ] ) ;
adj[ edges[ i] [ 1 ] ] . push_back ( edges[ i] [ 0 ] ) ;
degree[ edges[ i] [ 0 ] ] ++ ;
degree[ edges[ i] [ 1 ] ] ++ ;
}
queue< int > que;
for ( int i= 0 ; i< n; i++ ) {
if ( degree[ i] == 1 ) que. push ( i) ;
}
vector< int > res;
while ( ! que. empty ( ) ) {
res. clear ( ) ;
int cnt= que. size ( ) ;
while ( cnt-- ) {
int index= que. front ( ) ;
que. pop ( ) ;
res. push_back ( index) ;
for ( int t: adj[ index] ) {
degree[ t] -- ;
if ( degree[ t] == 1 ) que. push ( t) ;
}
}
}
return res;
}
} ;