生活随笔
收集整理的這篇文章主要介紹了
LeetCode 310. 最小高度树(图 聪明的BFS,从外向内包围)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
1. 題目
對于一個具有樹特征的無向圖,我們可選擇任何一個節(jié)點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函數(shù)找到所有的最小高度樹并返回他們的根節(jié)點。
格式
該圖包含 n 個節(jié)點,標記為 0 到 n - 1。給定數(shù)字 n 和一個無向邊 edges 列表(每一個邊都是一對標簽)。
你可以假設沒有重復的邊會出現(xiàn)在 edges 中。由于所有的邊都是無向邊, [0, 1]和 [1, 0] 是相同的,因此不會同時出現(xiàn)在 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]說明
:根據(jù)樹的定義,樹是一個無向圖,其中任何兩個頂點只通過一條路徑連接。 換句話說,一個任何沒有簡單環(huán)路的連通圖都是一棵樹。
樹的高度是指根節(jié)點和葉子節(jié)點之間最長向下路徑上邊的數(shù)量。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/minimum-height-trees
著作權歸領扣網(wǎng)絡所有。商業(yè)轉載請聯(lián)系官方授權,非商業(yè)轉載請注明出處。
2. 解題
2.1 暴力BFS
- 從每個節(jié)點開始BFS,記錄高度,選擇最小的高度的起點即可
- 節(jié)點很多的時候,會超時
class Solution {unordered_map
<int,unordered_set
<int>> g
;vector
<int> vertex
;queue
<int> q
;
public:vector
<int> findMinHeightTrees(int n
, vector
<vector
<int>>& edges
) {for(auto& e
: edges
){g
[e
[0]].insert(e
[1]);g
[e
[1]].insert(e
[0]);}bool visited
[n
];int minh
= INT_MAX
, h
;for(int i
= 0; i
< n
; i
++){memset(visited
, 0, sizeof(visited
));h
= 0;visited
[i
] = true;q
.push(i
);BFS(h
,visited
);if(h
< minh
){minh
= h
;vertex
.clear();vertex
.push_back(i
);}else if(h
== minh
)vertex
.push_back(i
);}return vertex
;}void BFS(int& h
, bool* visited
){int tp
, size
;while(!q
.empty()){size
= q
.size();while(size
--){tp
= q
.front();q
.pop();for(const int& id
: g
[tp
]){if(!visited
[id
]){q
.push(id
);visited
[id
] = true;}}}h
++;}}
};
優(yōu)化下
- 是最外圍的節(jié)點?是最外圍的,不用從他開始BFS,高度肯定不是最小的
- 見以下代碼,還是超時!!!
class Solution {unordered_map
<int,unordered_set
<int>> g
;vector
<int> vertex
;queue
<int> q
;vector
<int> lastLv
;
public:vector
<int> findMinHeightTrees(int n
, vector
<vector
<int>>& edges
) {for(auto& e
: edges
){g
[e
[0]].insert(e
[1]);g
[e
[1]].insert(e
[0]);}bool visited
[n
];bool outSide
[n
];memset(outSide
, 0, sizeof(outSide
));int minh
= INT_MAX
, h
= 0;for(int i
= 0; i
< n
; i
++){if(minh
> 2 && outSide
[i
])continue;memset(visited
, 0, sizeof(visited
));h
= 0;visited
[i
] = true;q
.push(i
);BFS(h
,visited
,outSide
);if(h
< minh
){minh
= h
;vertex
.clear();vertex
.push_back(i
);}else if(h
== minh
)vertex
.push_back(i
);}return vertex
;}void BFS(int& h
, bool* visited
, bool* outSide
){int tp
, size
;while(!q
.empty()){size
= q
.size();lastLv
.clear();while(size
--){tp
= q
.front();q
.pop();for(const int& id
: g
[tp
]){if(!visited
[id
]){q
.push(id
);visited
[id
] = true;lastLv
.push_back(id
);}}}h
++;}for(auto id
: lastLv
)outSide
[id
] = true;}
};
2.2 聰明的BFS
- 最低的高度樹,可能的root只有1個或者2個(相當于把一個數(shù)組平分兩半,奇偶可能)
- 那么從圖中最外圍的節(jié)點,開始找(出入度為1),把所有的出入度為1的節(jié)點push進入隊列
- 一層層的剝離節(jié)點,到遍歷的節(jié)點只剩下2個或者1時,即找到答案
class Solution {
public:vector
<int> findMinHeightTrees(int n
, vector
<vector
<int>>& edges
) {if(n
== 1)return {0};int i
, tp
, size
;unordered_map
<int,unordered_set
<int>> g
;vector
<int> vertex
;queue
<int> q
;for(auto& e
: edges
){g
[e
[0]].insert(e
[1]);g
[e
[1]].insert(e
[0]);}for(i
= 0; i
< n
; i
++)if(g
[i
].size() == 1)q
.push(i
);while(n
> 2){size
= q
.size();n
-= size
;while(size
--){tp
= q
.front();q
.pop();for(const int& id
: g
[tp
]){g
[id
].erase(tp
);if(g
[id
].size() == 1)q
.push(id
);}}}while(!q
.empty()){vertex
.push_back(q
.front());q
.pop();}return vertex
;}
};
總結
以上是生活随笔為你收集整理的LeetCode 310. 最小高度树(图 聪明的BFS,从外向内包围)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。