島嶼數量 ii
主要的想法是用並查集,改一下並查集的**就好了。假設每個相鄰的兩個格仔之間有條邊。整體的**感覺還能再優化些。
####首先將建個m*n長的陣列parent,表示每個格仔,m*n長的陣列rankx用於路徑壓縮。
####尋根的函式若parent[i] = i那麼就代表這個i位置就是乙個根節點。find_root函式尋找乙個節點的根節點。
ans ,res=
,0####ans最終的結果陣列,res每一步的結果。
parent =[-
1]*(m*n)
rankx =[0
]*(m*n)
deffind_root
(x,parent)
:while parent[x]
!= x:
x = parent[x]
return x
####union_xy用於合併兩個節點,這裡每一次加乙個positions[k] = [i,j]則這個點在parent的下標就為
##idx = i*n+j ,然後合併將[i,j]這個點和其上下左右合併。
defunion_xy
(x,y,parent,rankx)
: x = find_root(x,parent)
y = find_root(y,parent)
if x ==y:
return
0else
:if rankx[x]
> rankx[y]
: parent[y]
= x
elif rankx[y]
> rankx[x]
: parent[x]
= y else
: parent[x]
= y rankx[y]+=1
return
1for d in positions:
flag =
false
####用於判斷該節點是否已經是陸地
i,j = d[0]
,d[1
] idx = i*n+j
tmp =
if parent[idx]==-
1:
parent[idx]
= idx
)else
: flag =
true
####如果是就直接輸出上一輪得陸地塊數一樣多
)for k in
range(4
): x,y= dx[k]
+i,dy[k]
+j if x>=
0and x=
0and y
####如果[i,j]的上下左右沒有越界。
idy = x*n+y ####其在parent陣列的下標
if parent[idy]!=-
1:pv = find_root(idy,parent)
else:-
1)####if-else 用於記錄合併之前,[i,j]周圍節點的狀態,-1或者其根節點。
if parent[idy]!=-
1:union_xy(idx,idy,parent,rankx)
####合併[i,j]和滿足條件的四周節點
tmp2 =
[find_root(idx,parent)
]for k in
range(4
):####用於記錄合併後的[i,j]及周圍節點的狀態,
x,y= dx[k]
+i,dy[k]
+j if x>=
0and x=
0and y
idy = x*n+y
if parent[idy]!=-
1:pv = find_root(idy,parent)
else:-
1)t1,t2 =
,for i in
range
(len
(tmp)):
if tmp[i]!=-
1and tmp[i]
notin t1:
)if tmp2[i]!=-
1and tmp2[i]
notin t2:
)print
(t1,t2,tmp,tmp2)
if flag:
res +=
len(t2)
-len
(set
(t1)
)else
: res +=
len(t2)
-len
(set
(t1))+
1
並查集 島嶼數量
解答參考 島嶼數量官方解答 問題描述 給你乙個由 1 陸地 和 0 水 組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向和 或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。示例 1 輸入 grid 1 1 1 1 0 1 1 0 1 ...
力扣LeetCode 島嶼數量
給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000 輸出 1 示例 2 輸入 11000 11000 00100 0...
力扣 200 島嶼數量
給你乙個由 1 陸地 和 0 水 組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向和 或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。解題思路 dfs函式的作用 找到包含grid i j 格仔的島嶼的全部格仔,並將其全部置為 2 已訪...