1. 程式人生 > 其它 >力扣 leetcode 684. 冗餘連線 (python)

力扣 leetcode 684. 冗餘連線 (python)

技術標籤: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:
在這裡插入圖片描述