更複雜的並查集內容在
我們只需要知道並查集能幫助我們做什麼,和**框架解讀
通俗來說就是用乙個二維矩陣,起初大家都是孤立的
然後某個節點不斷得進行勢力擴張,合併其他節點,比如初始矩陣如下:
[[0,1,2]
[3,4,5]
[6,7,8]]
然後進行merge 操作,比如merge(2,1),merge(2,4),merge(2,7),merge(2,8)那麼矩陣變成
[[0,2,2]
[3,2,5]
[6,2,2]]
可以看到矩陣大多數都站在了2的一派,2是1,4,7,8的老大
這樣從矩陣座標[0,2]到座標[2,2]就構成一條路徑,現在你隱約可以感到,並查集可以解決涉及連通分量的問題
class
unionfind
:def
__init__
(self,size)
:#就是上文提到的初始矩陣
self.father =
[i for i in
range
(size)
]def
find
(self,x)
:#查詢x這個節點的最高層領導是誰
if self.father[x]
==x:
return x #自己就是最高層領導
#這邊其實可以直接else:return find(father[x])進行遞迴
#這樣賦值的目的是,路徑壓縮(將最高層領導作為自己的直屬上級)
self.father[x]
= self.find(self.father[x]
)return self.father[x]
defis_connected
(self,x,y)
:#你我老大是否是同乙個人
return self.find(x)
== self.find(y)
defmerge
(self,x,y)
: self.father[self.find(x)
]= self.find(y)
#x將y認作老大
舉個3*3的矩陣例子看下**細節
959. 由斜槓劃分區域
從基礎開始,將每個小格仔分成1,2,3,4,四個位置
分三種情況合併該單元格的四個部分
不同格仔相鄰的右和下肯定是可以合併的
這裡邊學到了如何用並查集判斷連通分量個數
這邊邊界判斷著急有點硬湊的感覺,有時間再改
#還是用上面並查集的介面
class
solution
:def
regionsbyslashes
(self, grid: list[
str])-
>
int:
n=len(grid)
n=n*n*
4 uf=unionfind(n)
i=0 level=
1for g in grid:
for g in g:
if i+
4>n:
break
if g==
" ":
uf.merge(i,i+1)
uf.merge(i,i+2)
uf.merge(i,i+3)
if g==
"/":
uf.merge(i,i+1)
uf.merge(i+
2,i+3)
if g==
"\\"
: uf.merge(i,i+2)
uf.merge(i+
1,i+3)
if i+
5uf.merge(i+
2,i+5)
if i+n*
4uf.merge(i+
3,i+n*4)
i+=4 level+=
1#重點理解最後一行,結合if self.father[x] ==x: return x,自己就是自己最高領導
return
sum(uf.father[i]
== i for i in
range
(n))
778. 水位上公升的泳池中游泳
解題思路簡單來說,就是時間從0-n^2,每一時刻都定位圖中對應水位的點
然後把它四周比它低的水位淹沒(有點我的世界的感覺)
每個時間都判斷起點終點是否連通
連通就返回當前時刻的值
class
solution
:def
swiminwater
(self, grid: list[list[
int]])
->
int:
#這邊為了省事函式套函式
deflegal
(x,y)
:return x >=
0and x < n and y >=
0and y < n
n=len(grid)
uf=unionfind(n*n)
index =[0
]*(n*n)
for n in
range
(n):
for m in
range
(n):
index[grid[n]
[m]]
=n*n+m #記錄每個水位的一維座標值
for i in
range
(n*n)
: x=index[i]
//n #還原稱二維座標,為了表示該點上下左右
y=index[i]
%n for direction in[[
1,0]
,[-1
,0],
[0,1
],[0
,-1]
]:newx=x+direction[0]
newy=y+direction[1]
if legal(newx,newy)
:if grid[newx]
[newy]
<=i:
#四周水位比當前水位低
uf.merge(n*newx+newy,index[i]
)if uf.is_connected(
0,n*n-1)
:return i
力扣305,島嶼數量,並查集。
島嶼數量 ii 主要的想法是用並查集,改一下並查集的 就好了。假設每個相鄰的兩個格仔之間有條邊。整體的 感覺還能再優化些。首先將建個m n長的陣列parent,表示每個格仔,m n長的陣列rankx用於路徑壓縮。尋根的函式若parent i i那麼就代表這個i位置就是乙個根節點。find root函...
並查集路徑壓縮 力扣547 並查集及其回滾
547.朋友圈 班上有 n 名學生。其中有些人是朋友,有些則不是。他們的友誼具有是傳遞性。如果已知 a 是 b 的朋友,b 是 c 的朋友,那麼我們可以認為 a 也是 c 的朋友。所謂的朋友圈,是指所有朋友的集合。給定乙個 n n 的矩陣 m,表示班級中學生之間的朋友關係。如果m i j 1,表示已...
力扣 223 場 周賽總結 並查集 狀態壓縮
1722.執行交換操作後的最小漢明距離 相似題目 1202.交換字串中的元素 1723.完成所有工作的最短時間 首先兩題剛拿到的時候思路都是正確的 3 的尋找連通區域和遍歷 和 4 的二分答案範圍來求解,總體難度感覺不高,但是還是沒有做出來。對於 3 對於並查集中的劃分連通區域不熟悉 利用map來處...