力扣 leetcode 684. 冗餘連線 (python)
阿新 • • 發佈:2021-01-19
技術標籤:pythonleetcode演算法leetcode資料結構python並查集
Topic:
在本問題中, 樹指的是一個連通且無環的無向圖。
輸入一個圖,該圖由一個有著N個節點 (節點值不重複1, 2, …, N) 的樹及一條附加的邊構成。附加的邊的兩個頂點包含在1到N中間,這條附加的邊不屬於樹中已存在的邊。
結果圖是一個以邊組成的二維陣列。每一個邊的元素是一對[u, v] ,滿足 u < v,表示連線頂點u 和v的無向圖的邊。
返回一條可以刪去的邊,使得結果圖是一個有著N個節點的樹。如果有多個答案,則返回二維陣列中最後出現的邊。答案邊 [u, v] 應滿足相同的格式 u < v。
Example_1:
輸入: [[1,2], [1,3], [2,3]]
輸出: [2,3]
解釋: 給定的無向圖為:
1
/ \
2 - 3
Example_2:
輸入: [[1,2], [2,3], [3,4], [1,4], [1,5]]
輸出: [1,4]
解釋: 給定的無向圖為:
5 - 1 - 2
| |
4 - 3
Solution:
本題模板來自於並查集模板
本題是並查集中最基礎的判斷環是否存在的問題的類似題目
樹是一個連通且無環的無向圖
在樹中多了一條附加的邊之後就會出現環
因此附加的邊即為導致環出現的邊
我們可以再每次新加邊時
對兩個節點進行判斷:
如果兩個節點在未加邊時未連通(根節點不同)
如果合併不會形成環,將這兩個節點連通(合併)
如果兩個節點在未加邊時已經連同(根節點相同)
則說明這兩個節點屬於相同的連通分量
如果合併就會形成環,直接返回此邊即可
最後如果全遍歷完也未形成環
返回空列表
Code:
class UnionFind:
def __init__(self):
"""
記錄每個節點的父節點
"""
self.father = {}
def find(self,x):
"""
查詢根節點
路徑壓縮
"""
root = x
while self.father[root] != None:
root = self.father[root]
return root
def merge(self,x,y):
"""
合併兩個節點
"""
root_x,root_y = self.find(x),self.find(y)
if root_x != root_y:
self.father[root_x] = root_y
def is_connected(self,x,y):
"""
判斷兩節點是否相連
"""
return self.find(x) == self.find(y)
def add(self,x):
"""
新增新節點
"""
if x not in self.father:
self.father[x] = None
class Solution:
def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
uf = UnionFind()
for i in range(1, len(edges) + 1):
uf.add(i)
for node1, node2 in edges:
if uf.is_connected(node1, node2) is False:
uf.merge(node1, node2)
else:
return [node1, node2]
return []
Result: