LeetCode 310. Minimum Height Trees
Description
For an undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
Example 1 :
Input: n = 4, edges = [[1, 0], [1, 2], [1, 3]] 0 | 1 / \ 23 Output: [1]
Example 2 :
Input: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]] 012 \ | / 3 | 4 | 5 Output: [3, 4]
Note:
- According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
- The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
描述
對於一個具有樹特徵的無向圖,我們可選擇任何一個節點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函式找到所有的最小高度樹並返回他們的根節點。
注意:
該圖包含 n 個節點,標記為 0 到 n - 1。給定數字 n 和一個無向邊 edges 列表(每一個邊都是一對標籤)。
你可以假設沒有重複的邊會出現在 edges 中。由於所有的邊都是無向邊, [0, 1]和 [1, 0] 是相同的,因此不會同時出現在 edges 裡。
示例 1:
輸入: n = 4, edges = [[1, 0], [1, 2], [1, 3]] 0 | 1 / \ 23 輸出: [1]
示例 2:
輸入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]] 012 \ | / 3 | 4 | 5 輸出: [3, 4]
說明:
- 根據樹的定義,樹是一個無向圖,其中任何兩個頂點只通過一條路徑連線。 換句話說,一個任何沒有簡單環路的連通圖都是一棵樹。
- 樹的高度是指根節點和葉子節點之間最長向下路徑上邊的數量。
思路
- 最小高度樹的根節點是圖中最長路徑的中間節點.
- 我們用一個 List[set()] 的結構儲存每個節點可以訪問到的其他節點。一般情況下應該使用字典,以節點為鍵,能夠遍歷到的節點組成的雜湊set為鍵,但由於題中的節點是從0開始的數字,我們可以用 List 來代替,索引就是鍵。
- 最長路徑的中間節點最多會有兩個:最長路徑有奇數個節點,則中間節點有 1 個;最長路徑有偶數個節點,則中間節點有 2 個。
- 基本思路是:找到所有的葉子節點,去掉所有葉子節點,找到新的所有葉子節點,去掉所有葉子節點 ... 直到剩下的節點個數小於等於2個。
# -*- coding: utf-8 -*- # @Author:何睿 # @Create Date:2019-02-17 13:46:09 # @Last Modified by:何睿 # @Last Modified time: 2019-02-17 14:15:30 class Solution: def findMinHeightTrees(self, n: 'int',edges: 'List[List[int]]') -> 'List[int]': # 如果只有一個節點,直接返回當前節點 if n == 1: return [0] # 路徑:記錄每個節點可以訪問到的所有節點 type:list[set()] # 更一般的情況是利用字典實現,利用節點作為鍵,節點能夠走到的所有節點 # 組成的set作為值,但是題中得節點為從0開始的數值,因此可以用list代替字典 paths = [set() for _ in range(n)] #找到每個節點可以走到的下一個節點 for node1, node2 in edges: paths[node1].add(node2) paths[node2].add(node1) # 找到所有的葉子節點 leaves = [node for node in range(n) if len(paths[node]) == 1] # root用於記錄剩下的節點 roots = n while roots > 2: # 更新剩下的節點個數 roots -= len(leaves) # 新的葉子節點 newleaves = [] for node in leaves: # 獲取葉節點的父節點 parent = paths[node].pop() # 從葉節點的父節點中刪除當前節點 paths[parent].remove(node) # 如果當前節點的父節點只能訪問一個節點,則新增到新葉節點中 if len(paths[parent]) == 1: newleaves.append(parent) leaves = newleaves return leaves
原始碼檔案在這裡 .
©本文首發於何睿的部落格 ,歡迎轉載,轉載需保留文章來源,作者資訊和本宣告.