# [1020] 飞地的数量
给你一个大小为 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 没有被包围,因为它在边界上。
示例 2:
输入:grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
输出:0
解释:所有 1 都在边界上或可以到达边界。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 500
grid[i][j] 的值为 0 或 1
这也是一道经典的 Flood Fill 问题,由于高度相似,解法就不具体赘述了,可参考 [695] 岛屿的最大面积
。
这里在计算岛屿面积时,需要多判断一次该岛屿边界是否在边缘处即可。
function numEnclaves(grid: number[][]): number {
let res = 0;
let count = 0;
let foundBound = false;
const direction = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
const rowLen = grid.length;
const colLen = grid[0].length;
for (let i = 0; i < rowLen; i++) {
for (let j = 0; j < colLen; j++) {
if (grid[i][j] === 1) {
count = 0;
foundBound = false;
backtrack(i, j);
if (!foundBound) {
res += count;
}
}
}
}
return res;
function backtrack(row: number, col: number) {
if (row < 0 || row >= rowLen || col < 0 || col >= colLen) return;
if (grid[row][col] !== 1) return;
if (row === 0 || row === rowLen - 1 || col === 0 || col === colLen - 1) {
foundBound = true;
}
grid[row][col] = 2;
count += 1;
for (const [i, j] of direction) {
backtrack(row + i, col + j);
}
}
}