class Solution:
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
def dfs(node, parent):
hgt = 0
for nei in adj[node]:
if nei == parent:
continue
hgt = max(hgt, 1 + dfs(nei, node))
return hgt
minHgt = n
res = []
for i in range(n):
curHgt = dfs(i, -1)
if curHgt == minHgt:
res.append(i)
elif curHgt < minHgt:
res = [i]
minHgt = curHgt
return resWhere is the number of vertices and is the number of edges.
class Solution:
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
dp = [[0] * 2 for _ in range(n)] # top two heights for each node
def dfs(node, parent):
for nei in adj[node]:
if nei == parent:
continue
dfs(nei, node)
curHgt = 1 + dp[nei][0]
if curHgt > dp[node][0]:
dp[node][1] = dp[node][0]
dp[node][0] = curHgt
elif curHgt > dp[node][1]:
dp[node][1] = curHgt
def dfs1(node, parent, topHgt):
if topHgt > dp[node][0]:
dp[node][1] = dp[node][0]
dp[node][0] = topHgt
elif topHgt > dp[node][1]:
dp[node][1] = topHgt
for nei in adj[node]:
if nei == parent:
continue
toChild = 1 + (dp[node][1] if dp[node][0] == 1 + dp[nei][0] else dp[node][0])
dfs1(nei, node, toChild)
dfs(0, -1)
dfs1(0, -1, 0)
minHgt, res = n, []
for i in range(n):
minHgt = min(minHgt, dp[i][0])
for i in range(n):
if minHgt == dp[i][0]:
res.append(i)
return resWhere is the number of vertices and is the number of edges.
class Solution:
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
if n == 1:
return [0]
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
def dfs(node, parent):
farthest_node = node
max_distance = 0
for nei in adj[node]:
if nei != parent:
nei_node, nei_distance = dfs(nei, node)
if nei_distance + 1 > max_distance:
max_distance = nei_distance + 1
farthest_node = nei_node
return farthest_node, max_distance
node_a, _ = dfs(0, -1)
node_b, diameter = dfs(node_a, -1)
centroids = []
def find_centroids(node, parent):
if node == node_b:
centroids.append(node)
return True
for nei in adj[node]:
if nei != parent:
if find_centroids(nei, node):
centroids.append(node)
return True
return False
find_centroids(node_a, -1)
L = len(centroids)
if diameter % 2 == 0:
return [centroids[L // 2]]
else:
return [centroids[L // 2 - 1], centroids[L // 2]]Where is the number of vertices and is the number of edges.
class Solution:
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
if n == 1:
return [0]
adj = defaultdict(list)
for n1, n2 in edges:
adj[n1].append(n2)
adj[n2].append(n1)
edge_cnt = {}
leaves = deque()
for src, neighbors in adj.items():
edge_cnt[src] = len(neighbors)
if len(neighbors) == 1:
leaves.append(src)
while leaves:
if n <= 2:
return list(leaves)
for _ in range(len(leaves)):
node = leaves.popleft()
n -= 1
for nei in adj[node]:
edge_cnt[nei] -= 1
if edge_cnt[nei] == 1:
leaves.append(nei)Where is the number of vertices and is the number of edges.