310. Minimum Height Trees
題目網址:https://leetcode.cn/problems/minimum-height-trees/
題意:給一數字
n
和n - 1
條無向邊的edges
list, 代表一包含n
個 node 編號從0
到n - 1
的 tree。可選擇 tree 中任意 node 作為 root。在所有可能的 tree 中, 具有最小高度的 tree 被稱為最小高度樹。
找到所有最小高度樹的 root 並按任意順序返回。
Solution 1:
想法:利用 Topological Sort + BFS, 我們發現若希望高度越小, 則 root 應選 degree 越大的。
下圖中, 紅圈以外的是 leaf, 若將這些點作為 root, 其樹高不可能為最小的, 原因如下:
若將 leaf 作為 root, 其樹高的路徑必「走進」紅圈, 再「走出」紅圈
若將 non-leaf 為 root, 其樹高的路徑只需「走出」紅圈
➔ 故可透過「剝洋蔥」的方式, 一層一層剝掉 degree = 1 的 node, 直到剩下 ≤ 兩個 node。
思考: 為何不是三個 node 就停呢? 因為三個 node 可以繼續剝下去
特殊情況:當 tree 只有一個 node 時, 則答案即為該 node 本身
class Solution { |
time:$O(n)$ ➔ $O(n+(n-1))$, 其實就是對圖進行 BFS 所需之時間複雜度 $O(V+E)$
- $O(V)$:
n
個 node - $O(E)$:
n - 1
條 edge, 因為 tree 是 acyclic
- $O(V)$:
space:$O(n)$ ➔ $O(n+(n-1))$, 因為
adj
為 $O(V + E)$,V
是因為要記錄所有點,E
是因為會記錄所有邊
Solution 2:
想法:利用 DFS, tree 中最長 path 的兩端點皆必為 leaf, 否則 path 可繼續拓展, 我們的目標就是找出最長 path 之中點
- 先隨機選取一個 node(可能不為 leaf), 並對其進行 dfs 取得離它最遠的點
n1
(第一個 leaf)- 對
n1
進行 dfs 取得離它最遠的點n2
(第二個 leaf)- 此時,
n1 -> n2
為 tree 中最長的 path, 其 path 之中點即為答案
- 若 path 長度為奇數, 則取
{path[len / 2]}
- 若 path 長度為偶數, 則取
{path[(len / 2) - 1], path[len / 2]}
e.g. 下圖中
首先選取
1
並做 dfs 取得n1 = 6
再對
n1
做 dfs 得n2 = 7
。n1 -> n2
之 path 長度為 5(6 -> 4 -> 1 -> 5 -> 7
)取 path 中點 1 會得到最小高度樹
class Solution { |
- time:$O(n)$ ➔ $O(n+(n-1))$, 其實就是對圖進行 DFS 所需之時間複雜度 $O(V+E)$
- $O(V)$:
n
個 node - $O(E)$:
n - 1
條 edge, 因為 tree 是 acyclic
- $O(V)$:
- space:$O(n)$ ➔ $O(n+(n-1))$, 因為
adj
為 $O(V + E)$,V
是因為要記錄所有點,E
是因為會記錄所有邊