题目:
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 3return
[1]
Example
2:
Given
n
= 6
, edges
= [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 \ | / 3 | 4 | 5return
[3,
4]
思路:
这题要求我们对于一棵树中,找出一个结点,让它成为根的时候,整个树的高度最小,返回所有可能成为根的结点序列。为了解决这个问题,有一个思路是在每次迭代中,将野子节点删去,直到最后可能剩下一个结点或者两个结点,这一个或两个结点则是我们所要求的结点。可以试着这样去理解这个过程,所求的根结点就是到叶子结点的距离最大值中最小的那个点,假设一开始同时从每个叶子出发向中心靠拢,每走一步就删掉原来的结点,这样就逐步向中心靠拢,在最小的步数内能同时汇聚在一个或两个结点上,这就是我们要求的结果。
程序:
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
vector<vector<int> > adj(n);
vector<int> degree(n,0);
set<int> s;
vector<int> res;
for(int i = 0;i < n;i++)
s.insert(i);
for(int i = 0;i < edges.size();i++)
{
adj[edges[i].first].push_back(edges[i].second);
adj[edges[i].second].push_back(edges[i].first);
degree[edges[i].first]++;
degree[edges[i].second]++;
}
while(n > 2)
{
set<int> temp;
set<int>::iterator p;
for(int i = 0;i < degree.size();i++)
{
if(degree[i] == 1)
{
temp.insert(i);
s.erase(i);
n--;
degree[i]--;
}
}
for(p = temp.begin();p != temp.end();p++)
{
int u = *p;
for(int i = 0;i < adj[u].size();i++)
degree[adj[u][i]]--;
}
}
set<int>::iterator p = s.begin();
for(;p != s.end();p++)
res.push_back(*p);
return res;
}
};