https://labuladong.online/algo/frequency-interview/island-dfs-summary/
岛屿问题的核心: 用dfs/bfs算法遍历二维数组
1. 岛屿数量
https://leetcode.cn/problems/number-of-islands/description/
思路:dfs遍历岛屿,找到岛屿后把整个岛屿淹掉(置为0)
class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
def traverse(i, j):
M, N = len(grid), len(grid[0])
if i >= M or i < 0 or j >= N or j < 0 or grid[i][j] == "0":
return
grid[i][j] = "0"
traverse(i+1, j)
traverse(i-1, j)
traverse(i, j+1)
traverse(i, j-1)
if not grid:
return 0
res = 0
M = len(grid)
N = len(grid[0])
for i in range(M):
for j in range(N):
if grid[i][j] == "1":
res += 1
traverse(i, j)
return res
2. 封闭岛屿数量
https://leetcode.cn/problems/number-of-closed-islands/description/
先用dfs函数把边缘的岛屿淹掉,再统计岛屿数量
class Solution(object):
def closedIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def dfs(i, j):
m, n = len(grid), len(grid[0])
if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 1:
return
grid[i][j] = 1
dfs(i+1, j)
dfs(i-1, j)
dfs(i, j+1)
dfs(i, j-1)
if not grid:
return 0
m, n = len(grid), len(grid[0])
res = 0
for i in range(m):
dfs(i, 0)
dfs(i, n-1)
for j in range(n):
dfs(0, j)
dfs(m-1, j)
for i in range(m):
for j in range(n):
if grid[i][j] == 0:
dfs(i, j)
res += 1
return res
3. 飞地的数量
class Solution(object):
def numEnclaves(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if not grid:
return 0
def dfs(i, j):
m, n = len(grid), len(grid[0])
if i < 0 or i >= m or j < 0 or j >= n:
return
if grid[i][j] == 0:
return
grid[i][j] = 0
dfs(i+1, j)
dfs(i-1, j)
dfs(i, j+1)
dfs(i, j-1)
m, n = len(grid), len(grid[0])
for i in range(m):
dfs(i, 0)
dfs(i, n-1)
for j in range(n):
dfs(0, j)
dfs(m-1, j)
res = 0
for i in range(1, m-1):
for j in range(1, n-1):
if grid[i][j] == 1:
res += 1
return res
4. 岛屿的最大面积
https://leetcode.cn/problems/max-area-of-island/
class Solution(object):
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def dfs(i, j):
m, n = len(grid), len(grid[0])
if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 0:
return
grid[i][j] = 0
self.cnt += 1
dfs(i+1, j)
dfs(i-1, j)
dfs(i, j+1)
dfs(i, j-1)
if not grid:
return 0
m, n = len(grid), len(grid[0])
self.cnt = 0
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
self.cnt = 0
dfs(i, j)
res = max(res, self.cnt)
self.cnt = 0
return res
5. 子岛屿数量
https://leetcode.cn/problems/count-sub-islands/
写法一:
class Solution(object):
def countSubIslands(self, grid1, grid2):
"""
:type grid1: List[List[int]]
:type grid2: List[List[int]]
:rtype: int
"""
if not grid2:
return 0
def dfs(i, j):
m, n = len(grid2), len(grid2[0])
if i < 0 or i >= m or j < 0 or j >= n:
return True
if grid2[i][j] == 0:
return True
else:
grid2[i][j] = 0
x = dfs(i+1, j)
x = dfs(i-1, j) and x
x = dfs(i, j+1) and x
x = dfs(i, j-1) and grid1[i][j] == 1 and x
return x
m, n = len(grid2), len(grid2[0])
res = 0
for i in range(m):
for j in range(n):
if grid2[i][j] == 1 and dfs(i, j):
print(i, j)
res += 1
return res
写法二:
先淹掉一部分grid==0的,剩下的都是子岛屿
class Solution(object):
def countSubIslands(self, grid1, grid2):
"""
:type grid1: List[List[int]]
:type grid2: List[List[int]]
:rtype: int
"""
if not grid2:
return 0
def dfs(i, j):
m, n = len(grid2), len(grid2[0])
if i < 0 or i >= m or j < 0 or j >= n or grid2[i][j] == 0:
return
grid2[i][j] = 0
x = dfs(i+1, j)
x = dfs(i-1, j)
x = dfs(i, j+1)
x = dfs(i, j-1)
return
m, n = len(grid2), len(grid2[0])
res = 0
for i in range(m):
for j in range(n):
if grid1[i][j] == 0:
dfs(i,j)
for i in range(m):
for j in range(n):
if grid2[i][j] == 1:
dfs(i, j)
res += 1
return res