You are given an n x n
binary matrix grid
. You are allowed to change at most one 0
to be 1
.
Return the size of the largest island in grid
after applying this operation.
An island is a 4-directionally connected group of 1
s.
Example 1:
Input: grid = [[1,0],[0,1]] Output: 3 Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.
Example 2:
Input: grid = [[1,1],[1,0]] Output: 4 Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.
Example 3:
Input: grid = [[1,1],[1,1]] Output: 4 Explanation: Can't change any 0 to 1, only one island with area = 4.
Constraints:
n == grid.length
n == grid[i].length
1 <= n <= 500
grid[i][j]
is either0
or1
.
又是一道岛屿题,虽然这道题难度级别为hard,但是如果已经掌握了并查集(Union Find), 而且会用Union Find解答Leetcode200. Number of Islands 和Leetcode695. Max Area of Island,就会发现这道题就不再是hard,其实跟前面两道题类似,同样可以用并查集(Union Find)来解答。
题目说最多可以把矩阵中一个值为0的点改为1使之成为陆地,值改成1后就可能把原来不相邻的岛屿连成一片变成一个更大的岛屿,求修改哪个点可以得到最大面积的岛屿。因此本题只要在Leetcode200. Number of Islands 或Leetcode695. Max Area of Island的基础上再遍历一遍矩阵,遍历时遇到值为0点,就判断其上下左右的值,如果值为1表示存在岛屿,再把上下左右存在的岛屿面积加起来(代码实现时要注意有重复的岛屿)再加上1就是更大岛屿的面积,遍历过程中更新最大岛屿的面积,遍历完成后得到的最大岛屿的面积就是要求的答案。
class UnionFind :
def __init__(self, n) :
self.parent = list(range(0, n))
self.size = [1] * n
self.maxsize = 1
def find(self, i) :
if self.parent[i] != i :
self.parent[i] = self.find(self.parent[i])
return self.parent[i]
def merge(self, x, y) :
px, py = self.find(x), self.find(y)
if px == py :
return
if self.size[px] < self.size[py] :
self.parent[px] = py
self.size[py] += self.size[px]
self.maxsize = max(self.size[py], self.maxsize)
else :
self.parent[py] = px
self.size[px] += self.size[py]
self.maxsize = max(self.size[px], self.maxsize)
class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
n = len(grid)
uf = UnionFind(n * n)
for i in range(n) :
for j in range(n) :
if grid[i][j] == 1 :
if uf.maxsize == 0 :
uf.maxsize = 1
if i + 1 < m and grid[i + 1][j] == 1 :
uf.merge(i * n + j, (i + 1) * n + j )
if j + 1 < n and grid[i][j + 1] == 1 :
uf.merge(i * n + j, i * n + j + 1)
res = uf.maxsize
for i in range(m) :
for j in range(n) :
if grid[i][j] == 0 :
seen = set()
for ni, nj in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)) :
if ni >= 0 and ni < m and nj >= 0 and nj < n and grid[ni][nj] == 1 :
seen.add(uf.find(ni * n + nj))
area = 1
for x in seen:
area += uf.size[x]
res = max(res, area)
return res