310. 最小高度樹
阿新 • • 發佈:2020-07-28
對於一個具有樹特徵的無向圖,我們可選擇任何一個節點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函式找到所有的最小高度樹並返回他們的根節點。
格式
該圖包含n個節點,標記為0到n - 1。給定數字n和一個無向邊edges列表(每一個邊都是一對標籤)。
你可以假設沒有重複的邊會出現在edges中。由於所有的邊都是無向邊, [0, 1]和[1, 0]是相同的,因此不會同時出現在edges裡。
示例 1:
輸入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
輸出: [1]
示例 2:
輸入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
輸出: [3, 4]
說明:
根據樹的定義,樹是一個無向圖,其中任何兩個頂點只通過一條路徑連線。 換句話說,一個任何沒有簡單環路的連通圖都是一棵樹。
樹的高度是指根節點和葉子節點之間最長向下路徑上邊的數量
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/minimum-height-trees
1 //dfs 超時 2 class Solution { 3 public: 4 map<int, vector<int>> MAP; 5 vector<int> res; 6 int MAX_DEPTH = INT_MAX; 7 vector<int> visited; 8 int getDepth(int root, int depth) 9 { 10 int max_depth = depth;11 visited[root] = 1; 12 for (auto item : MAP[root]) 13 { 14 if (!visited[item]) 15 { 16 //cout << root << " " << item << endl; 17 max_depth = max(max_depth, getDepth(item, depth + 1)); 18 } 19 } 20 return max_depth; 21 } 22 //深度遍歷 求出以i為根節點的樹的高度 將高度最小的放入res中 23 vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { 24 visited.resize(n, 0); 25 for (auto item : edges) 26 { 27 MAP[item[0]].push_back(item[1]); 28 MAP[item[1]].push_back(item[0]); 29 } 30 for (int i = 0; i < n; i++) 31 { 32 for (int k = 0; k < n; k++)visited[k] = 0; 33 int depth = getDepth(i, 0); 34 //cout << depth << endl; 35 if (depth == MAX_DEPTH)res.push_back(i); 36 else if (depth < MAX_DEPTH) 37 { 38 MAX_DEPTH = depth; 39 res.clear(); 40 res.push_back(i); 41 } 42 } 43 return res; 44 } 45 };
//bfs 超時 class Solution { public: map<int, vector<int>> MAP; vector<int> res; int MAX_DEPTH = INT_MAX; vector<int> visited; queue<int> que; int bfs(int root) { que.push(root); int last = root; int level = 1; while (!que.empty()) { int t = que.front(); que.pop(); if (visited[t])continue; visited[t] = 1; for (auto item : MAP[t]) if (!visited[item]) que.push(item); if (last == t&& !que.empty()) { level++; last = que.back(); } } return level; } vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { visited.resize(n, 0); for (auto item : edges) { MAP[item[0]].push_back(item[1]); MAP[item[1]].push_back(item[0]); } for (int i = 0; i < n; i++) { for (int k = 0; k < n; k++)visited[k] = 0; int depth = bfs(i); if (depth == MAX_DEPTH)res.push_back(i); else if (depth < MAX_DEPTH) { MAX_DEPTH = depth; res.clear(); res.push_back(i); } } return res; } };
//1、統計每個結點的度 //2、將度為1的結點刪除 //3、再重複1-2步驟 直至還剩1/2個結點為止 class Solution { public: vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) { map<int, vector<int>> MAP; int left = n; vector<int> degree(n, 0); vector<int> left_node(n, 1); for (auto item : edges) { MAP[item[0]].push_back(item[1]); MAP[item[1]].push_back(item[0]); } for (auto item : MAP) degree[item.first] = item.second.size(); vector<int> to_deletes; while (left > 2) { to_deletes.clear(); for (int i = 0; i < n; i++) if (degree[i] == 1) { to_deletes.push_back(i); left--; left_node[i] = 0; degree[i]=0; } for(auto i:to_deletes) for(auto j:MAP[i]) if(left_node[j]) degree[j]--; } vector<int> res; for (int i = 0; i < n; i++)if (left_node[i])res.push_back(i); return res; } };