1. 题目描述
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]
2. 代码
2.1 特别版
根据题意,给定的图是一个具有“树”特征的图,因此该图是无环的(树是无环的),因此在讨论算法的时候,不需要考虑有环的情况(实际上以下算法对有环的情况是不成立的)。
a. 一种解题思路是:最小高度是最长路径的“一半”!
b. 另一种思路是,不断删除叶子结点,最终会达到根结点,如果具有最小高度树的根结点是唯一的,那么最后只会剩下一个结点,否则剩下两个结点(不会有其他情况,思考为什么?)
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
//邻接表
vector<unordered_set<int>> adj(n);
for(pair<int, int> e : edges) {
adj[e.first].insert(e.second);
adj[e.second].insert(e.first);
}
//只有一个结点
vector<int> current;
if(n == 1) {
current.push_back(0);
return current;
}
//最底层叶结点
for(int i = 0; i < adj.size(); ++i) {
if(adj[i].size() == 1) {
current.push_back(i);
}
}
//不断删除叶结点,直到根结点
while(true) {
vector<int> next;
for(int u : current) {
for(int v : adj[u]) {
adj[v].erase(u);
if(adj[v].size() == 1) next.push_back(v);
}
}
//如果next为空,那么必定是剩下两个结点或一个结点
//思考为什么?
if(next.size() == 0)
return current;
current = next;
}
}
};
注:如果current最后只剩下一个结点的话,那么下一个next不加增加,第二层for循环不再进入,next为空。
如果current最后一趟剩下两个结点的话,那么从第二层for循环出来后,adj[v]的size为0,next为空。
2.2 小白版
用常规的BFS,会超时,以下是Time Exceeding代码。注意还有内存空间上也有较大开销。
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
vector<vector<int>> vE(n,vector<int>(n,-1));
for(int i = 0; i < edges.size(); i++) {
vE[edges[i].first].push_back(edges[i].second);
vE[edges[i].second].push_back(edges[i].first);
}
int vector<int> res;
vector<int> height(n,0);
for(int u = 0; u < n; u++){
height[u] = bfs(u, vE);
}
sort(height.begin(), height.end());
int min = height[0];
res.push_back(min);
for(int h = 1; h < height.size(); h++) {
if(h == min) {
res.push_back(h);
}
}
return res;
}
int bfs(int u, vector<vector<int>>& vE) {
queue<int> q;
q.push(u);
int level = 0;
while(!q.empty()) {
level++;
for(int s = q.size(); s > 0; s--) {
int v = q.front();
q.pop();
for(int i = 0; i < vE[v].size(); i++) {
q.push(vE[v][i]);
}
}
}
return level;
}
};
邮箱联系:sysuygm@163.com
欢迎赐教!