# [1254] 统计封闭岛屿的数目
有一个二维矩阵 grid ,每个位置要么是陆地(记号为 0 )要么是水域(记号为 1 )。
我们从一块陆地出发,每次可以往上下左右 4 个方向相邻区域走,能走到的所有陆地区域,我们将其称为一座「岛屿」。
如果一座岛屿 完全 由水域包围,即陆地边缘上下左右所有相邻区域都是水域,那么我们将其称为 「封闭岛屿」。
请返回封闭岛屿的数目。
示例 1:
输入:grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
输出:2
解释:
灰色区域的岛屿是封闭岛屿,因为这座岛屿完全被水域包围(即被 1 区域包围)。
示例 2:
输入:grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
输出:1
示例 3:
输入:grid = [[1,1,1,1,1,1,1], [1,0,0,0,0,0,1], [1,0,1,1,1,0,1], [1,0,1,0,1,0,1], [1,0,1,1,1,0,1], [1,0,0,0,0,0,1], [1,1,1,1,1,1,1]]
输出:2
提示:
1 <= grid.length, grid[0].length <= 100 0 <= grid[i][j] <=1
这道题是 [200] 岛屿数量
岛屿问题的变种,只是求解变为了不在边界上的岛屿数量。
那么解决思路也很简单,我们先淹没掉在边界上的岛屿,在开始计数就行了。
function closedIsland(grid: number[][]): number {
let res = 0;
const width = grid[0].length;
const height = grid.length;
// 先淹没掉四周的岛屿
for (let i = 0; i < height; i++) {
// 左右两侧岛屿淹没
floodFill(i, 0);
floodFill(i, width - 1);
}
for (let j = 0; j < width; j++) {
// 上下两侧岛屿淹没
floodFill(0, j);
floodFill(height - 1, j);
}
// 在查询中间的岛屿,并增加计数器
for (let i = 1; i < height - 1; i++) {
for (let j = 1; j < width - 1; j++) {
if (grid[i][j] === 0) {
res += 1;
floodFill(i, j);
}
}
}
return res;
function floodFill(i: number, j: number) {
// 越界返回
if (i < 0 || i >= height || j < 0 || j >= width) return;
// 已遍历过,或者不为陆地,返回
if (grid[i][j] === 1) return;
grid[i][j] = 1;
floodFill(i - 1, j);
floodFill(i + 1, j);
floodFill(i, j - 1);
floodFill(i, j + 1);
}
}