Problem
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n
nodes which are labeled from 0
to n - 1
. You will be given the number n
and a list of undirected edges
(each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
Example 1:
Given n = 4
, edges = [[1, 0], [1, 2], [1, 3]]
0 | 1 / \ 2 3
return [1]
Example 2:
Given n = 6
, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 \ | / 3 | 4 | 5
return [3, 4]
Solution
class Solution {
void buildGraph(const vector<pair<int, int>>& edges, vector<list<int>>& graph, vector<int>& inArr){
for( auto edge : edges){
int i = edge.first, j = edge.second;
graph[i].push_back(j);
graph[j].push_back(i);
inArr[i]++;
inArr[j]++;
}
}
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
if( n == 0) return vector<int>();
if( edges.empty()) return vector<int>(1,0);
// build graph and in arr
vector<int> inArr(n, 0);
vector<list<int>> graph(n, list<int>());
buildGraph(edges, graph, inArr);
// bfs traverse
vector<int> curLvl, nextLvl;
for( int i = 0; i < inArr.size() ; i++) {
if( inArr[i] == 1) {
curLvl.push_back(i);
}
}
vector<int> rst (curLvl.begin(), curLvl.end());
while(!curLvl.empty()) {
int i = curLvl.back(); curLvl.pop_back();
int j = graph[i].front();
inArr[i]--;
for( int j : graph[i] ) {
if ( --inArr[j] == 1 ) {
nextLvl.push_back(j);
}
}
if(curLvl.empty()) {
if(nextLvl.empty()) return rst;
rst = nextLvl;
swap(curLvl, nextLvl);
}
}
return rst;
}
};