1. 程式人生 > 實用技巧 >310. 最小高度樹

310. 最小高度樹

對於一個具有樹特徵的無向圖,我們可選擇任何一個節點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函式找到所有的最小高度樹並返回他們的根節點。

格式

該圖包含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;
    }
};