C++ UnionFind解難題Leetcdoe 827 Making A Large Island
嘗試UnionFind解決。由於該題目透過最多翻轉 1 個額外的 0 單元來詢問最大島嶼的大小;使用Size優化而不是rank。
[Python解請進]
-----
Try UnionFind to solve. Since the question asks the size of the largest island by flipping at most 1 extra 0-cell; the Size -optimization is used instead of rank.
[codes on Leetcode]https://leetcode.com/problems/making-a-large-island/solutions/6350236/unionfind-with-size-member-vs-dfs-vs-bfs-39ms-beats-99-53/
[Tree/Graph playlist]https://www.youtube.com/watch?v=bna7aw7dkPY&list=PLYRlUBnWnd5Kt0-3un43cwY6yT_il8NWe
class UnionFind:
def __init__(self, N):
self.root = list(range(N))
self.Size = [1]*N
def Find(self, x):
if self.root[x] != x:
self.root[x] = self.Find(self.root[x]) # path compression
return self.root[x]
def Union(self, x, y):
x = self.Find(x)
y = self.Find(y)
if x==y: return False
if self.Size[x] > self.Size[y]:
self.Size[x] += self.Size[y]
self.root[y]=x
else:
self.Size[y] += self.Size[x]
self.root[x]=y
return True
class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
n=len(grid)
N=n*n
d=(0, 1, 0, -1, 0)
def inside(i, j):
return 0<=i<n and 0<=j<n
def idx(i, j):
return i*n+j
G=UnionFind(N)
maxSz=1
for i, row in enumerate(grid):
for j, x in enumerate(row):
if x==1:
a=idx(i, j)
D=grid[i+1][j] if i<n-1 else 0
R=grid[i][j+1] if j<n-1 else 0
if D>0:
b=a+n
if G.Union(a, b):
maxSz=max(maxSz, G.Size[G.Find(a)])
if R>0:
b=a+1
if G.Union(a, b):
maxSz=max(maxSz, G.Size[G.Find(a)])
for i, row in enumerate(grid):
for j, x in enumerate(row):
if x==0:
component=set()
for a in range(4):
r, s=i+d[a], j+d[a+1]
if inside(r, s) and grid[r][s]==1:
component.add(G.Find(idx(r, s)))
if len(component)==0: continue
sz=1+sum(G.Size[c] for c in component)
maxSz=max(maxSz, sz)
return maxSz
沒有留言:
張貼留言