https://leetcode.cn/problems/number-of-enclaves/
给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。
一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。
返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。
示例 1:
输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出:3
解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。
class Solution:
def numEnclaves(self, grid: List[List[int]]) -> int:
# 解题包括3个部分:1、定义淹没函数,2、淹没四周陆地,3、两层for循环
# 本题和1254题类似,区别在于本题不需要将遍历过的封闭岛屿淹没掉
# 也就是求所有陆地的数量,而不是岛屿的数量
m, n = len(grid), len(grid[0])
def dfs(i, j): # 淹没函数
if not 0 <= i < m or not 0 <= 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) # 右(包括右的上下左右,所有递归)
# def bfs(i, j): # 淹没函数
# q = [[i, j]]
# while q:
# [i, j] = q.pop(0)
# if not 0 <= i < m or not 0 <= j < n:
# continue
# if grid[i][j] == 0:
# continue
# grid[i][j] = 0
# q += [[i - 1, j], [i + 1, j], [i, j - 1], [i, j + 1]]
for i in range(m):
dfs(i, 0) # 把所有与最左列陆地相连的陆地(包括最左列)都淹掉
dfs(i, n - 1) # 把所有与最右列陆地相连的陆地(包括最右列)都淹掉
for j in range(n):
dfs(0, j) # 把所有与首行陆地相连的陆地(包括首行)都淹掉
dfs(m - 1, j) # 把所有与最下行陆地相连的陆地(包括最下行)都淹掉
# 通过以上2个淹没遍历,会把所有与边界相连的岛屿全部淹没
# 剩下遍历的都是封闭岛屿
cnt = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
cnt += 1
return cnt