diff --git a/cpp/minimum-height-trees.cpp b/cpp/minimum-height-trees.cpp new file mode 100644 index 0000000..120f7c1 --- /dev/null +++ b/cpp/minimum-height-trees.cpp @@ -0,0 +1,80 @@ +#include +#include +#include + +struct Solution { + using graph_t = std::vector>; + + public: + std::vector + findMinHeightTrees(int n, const std::vector> &edges) { + auto g = graph(n, edges); + + std::vector visited(n); + auto nodes = leafs(g, visited); + auto d = degrees(g); + + std::vector min_height_roots; + while (!nodes.empty()) { + auto size = nodes.size(); + min_height_roots.clear(); + + for (auto i = 0u; i < size; ++i) { + auto u = nodes.front(); + nodes.pop(); + + min_height_roots.push_back(u); + for (auto v : g[u]) { + if (visited[v]) { + continue; + } + + if ((--d[v]) == 1) { + visited[v] = true; + nodes.push(v); + } + } + } + } + + return min_height_roots; + } + + private: + graph_t graph(int n, const graph_t &edges) { + graph_t neighbors(n); + + for (const auto &e : edges) { + auto [u, v] = std::make_pair(e[0], e[1]); + neighbors[u].push_back(v); + neighbors[v].push_back(u); + } + + return neighbors; + } + + std::queue leafs(const graph_t &g, std::vector &visited) { + std::queue nodes; + + for (auto u = 0u; u < g.size(); ++u) { + if (g[u].size() >= 2) { + continue; + } + + visited[u] = true; + nodes.push(u); + } + + return nodes; + } + + std::vector degrees(const graph_t &g) { + std::vector d(g.size()); + + for (auto i = 0u; i < g.size(); ++i) { + d[i] = g[i].size(); + } + + return d; + } +};