力扣 通俗易懂並查集 月整理

2021-10-18 10:32:51 字數 3408 閱讀 2912

更複雜的並查集內容在

我們只需要知道並查集能幫助我們做什麼,和**框架解讀

通俗來說就是用乙個二維矩陣,起初大家都是孤立的

然後某個節點不斷得進行勢力擴張,合併其他節點,比如初始矩陣如下:

[[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來處...