LeetCode 310. Minimum Height Trees
目錄
題目描述
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]
分析
這道題的目的是求無向圖中高度最小的樹,在一個不存在環的無向圖中,高度最小的樹的根只有一個或兩個,若存在三個,則三點必構成一條鏈,中間的點所對應的樹高度會更小,以此類推。
- 方法一:可以通過暴力求解的方式,對無向圖中每一個點採用深度搜索,從而獲得每一個點作為樹的根時對應的樹的高度,找到高度最小的樹。但這種方法的過於複雜,會導致超時。
- 方法二:通過對問題進行分析,尋找高度最小的樹,就是尋找最中心的點,則可以迴圈刪除所有葉節點,最終留下的點則為所求根。
最終結果
方法一:
class Solution {
public:
int max = 0;
void dfs(int num, int depth, int n, int* graph, int visit[]) {
visit[num] = 1;
if (depth > max) max = depth;
for(int i = 0; i < n; i++) {
if (visit[i] == 0 && graph[num*n+i] == 1) {
dfs(i, depth+1, n, graph, visit);
}
}
return;
}
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
vector<int> count(n);
int graph[n][n] = {0};
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
graph[i][j] = 0;
}
}
for (vector<pair<int, int>>::iterator it = edges.begin(); it != edges.end(); it++) {
graph[(*it).first][(*it).second] = 1;
graph[(*it).second][(*it).first] = 1;
}
for (int i = 0; i <n; i++) {
int visit[n] = {0};
int depth = 0;
max = 0;
dfs(i, depth, n, (int*)graph, visit);
count[i] = max;
}
vector<int> result;
int min = count[0];
for (int i = 0; i < n; i++) {
if (count[i] < min) {
min = count[i];
result.clear();
result.push_back(i);
} else if (count[i] == min) {
result.push_back(i);
}
}
return result;
}
};
方法二:
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
vector<vector<int>> list(n);
vector<int> degree(n);
vector<int> res;
for (auto& p: edges) {
list[p.first].push_back(p.second);
degree[p.first] ++;
list[p.second].push_back(p.first);
degree[p.second] ++;
}
while (n > 2) {
vector<int> del;
for (int i = 0; i < degree.size(); i++) {
if (degree[i] == 1)
del.push_back(i);
}
for (auto p: del) {
degree[p] = -1;
n --;
for (auto t: list[p]) {
degree[t] --;
}
}
}
for (int i = 0; i < degree.size(); i++) {
if (degree[i] >= 0)
res.push_back(i);
}
return res;
}
};