310. 最小高度樹 - 力扣(LeetCode)
參考題解:
演算法邏輯:演算法的核心思路是逐層剪去葉子節點,直到剩下的節點是最小高度樹的根。
示例:
假設有如下的樹結構:
0 / \ 1 2 / \ 3 4
初始時,葉子節點是1
、3
和4
,剪掉這些葉子節點後,樹變成:
0 \ 2
再次剪掉葉子節點2
,最終剩下的節點是0,0就是最小高度樹的根節點。
相同的邊,還有一種最小高度數的情況是:
2 / \ \ 3 4 0 \ 1
初始時剪掉葉子節點3,4,1;再次剪掉葉子節點0,最終剩下的節點是2,2就是最小高度數的根節點。
具體程式碼如下:
class Solution { public: vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { vector<int> res; // 如果只有一個節點,那麼它就是最小高度樹 if (n == 1) { res.push_back(0); return res; } // 建立各個節點的出度表 vector<int> degree(n, 0); // 建立圖關係,在每個節點的列表中儲存相連節點 vector<vector<int>> map(n); for (const auto& edge : edges) { degree[edge[0]]++; degree[edge[1]]++; // 出度++ map[edge[0]].push_back(edge[1]); // 新增相鄰節點 map[edge[1]].push_back(edge[0]); } // 建立佇列 queue<int> q; // 把所有出度為1的節點,也就是葉子節點入隊 for (int i = 0; i < n; ++i) { if (degree[i] == 1) { q.push(i); } } // 迴圈條件是佇列不空 while (!q.empty()) { res.clear(); // 每層迴圈都要new一個新的結果集合 int size = q.size(); // 每一層的節點的數量 for (int i = 0; i < size; ++i) { int cur = q.front(); q.pop(); res.push_back(cur); // 將當前節點加入結果集 for (int neighbor : map[cur]) { degree[neighbor]--; if (degree[neighbor] == 1) { q.push(neighbor); // 如果是葉子節點,入隊 } } } } return res; // 返回最後一次儲存的列表 } };