bfs+topological sort O(n) time O(n) space
从外往里『剥洋葱』直到还剩1到2个节点为止,如果设置一个超级源点连接每个1度的点,则相当于单源最短路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public: vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { if (n < 2) return {0}; vector<unordered_set<int>> g(n); for (const auto &e : edges) { g[e[0]].insert(e[1]); g[e[1]].insert(e[0]); } list<int> q; for (int i = 0; i < n; ++i) { if (g[i].size() == 1) { q.push_back(i); } } while (n > 2) { n -= size(q); for (int i = size(q); i > 0; --i) { int u = q.front(); q.pop_front(); for (int v : g[u]) { g[v].erase(u); if (g[v].size() == 1) { q.push_back(v); } } } } return vector<int>(begin(q), end(q)); } };
|
纯topological sort O(n2) time O(n) space
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public: vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { if (n < 2) return {0}; unordered_map<int, unordered_set<int>> g; for (const auto &e : edges) { g[e[0]].insert(e[1]); g[e[1]].insert(e[0]); } vector<int> res; while (!g.empty()) { res.clear(); for (const auto &[i, _] : g) { if (g.count(i) && g[i].size() < 2) { res.push_back(i); } } for (int u : res) { for (int v : g[u]) { g[v].erase(u); } g.erase(u); } } return res; } };
|