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 :
Input:n = 4, edges = [[1, 0], [1, 2], [1, 3]]0 | 1 / \ 2 3 Output:[1]
Example 2 :
Input:n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]0 1 2 \ | / 3 | 4 | 5 Output:[3, 4]
解:
本质是求树的直径,树的直径的求法是1:从任意点进行BFS或DFS找到离他最远的点,此点是直径的一个端点,2:再以此点进行BFS或DFS找到离他最远的点即为直径的另一个端点。
1:树的特征:任意两个点之间有且只有一条路径
2:即便存在多条直径,中位点是同一个,这里不作详细证明
此题不是求直径长度,而是求直径中位点,所以在BFS时记录每一个结点的前序,最后通过不断寻找前序才能得到中位点。
此题用DFS超时,改用BFS,代码:
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int> >& edges) {
vector<vector<int> > temp(n);
for (int i = 0; i < edges.size(); i++) {
temp[edges[i].first].push_back(edges[i].second);
temp[edges[i].second].push_back(edges[i].first);
}
//从0找最远点
vector<int> visited(n, 0);
visited[0] = 1;
queue<int> bfs;
bfs.push(0);
int f;
while (!bfs.empty()) {
f = bfs.front();
bfs.pop();
for (int i = 0; i < temp[f].size(); i++) {
if (visited[temp[f][i]] == 0) {
visited[temp[f][i]] = 1;
bfs.push(temp[f][i]);
}
}
}
//找直径另一端点
vector<int> edgeLen(n, -1);
edgeLen[f] = 0;
vector<int> edgePre(n, 0);
queue<int> bfs1;
bfs1.push(f);
while (!bfs1.empty()) {
f = bfs1.front();
bfs1.pop();
for (int i = 0; i < temp[f].size(); i++) {
if (edgeLen[temp[f][i]] == -1) {
edgeLen[temp[f][i]] = edgeLen[f]+1;
edgePre[temp[f][i]] = f;
bfs1.push(temp[f][i]);
}
}
}
//通过pre寻找到中位点
int maxlen =edgeLen[f];
int midpos = f;
vector<int> res;
if (maxlen % 2 == 0) {
for (int j = 0; j < maxlen/2; j++) {
midpos = edgePre[midpos];
}
res.push_back(midpos);
} else {
for (int j = 0; j < maxlen/2; j++) {
midpos = edgePre[midpos];
}
res.push_back(midpos);
midpos = edgePre[midpos];
res.push_back(midpos);
}
return res;
}
};
本文介绍了一种算法,用于寻找给定树形图中的最小高度树。通过两次广度优先搜索(BFS)找到树的直径端点,并进一步确定直径中位点作为最小高度树的根节点。
877

被折叠的 条评论
为什么被折叠?



