Leetcode第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

 

编程思想:泛洪算法

实现思路:题目明确0表示陆地,1表示水域,要求找到网格内所有的封闭岛屿数目,通过分析可以发现边界上(i = 0, i = lineLength - 1, j = 0, j = columnLength - 1)与值为0相连的陆地(0标识)

     肯定不会构成封闭岛屿,那么我们可以利用泛红算法将边界上与值为0的陆地(0标识)全部置为水域(1标识),然后再在矩阵的非边界内寻找值等于0的陆地,当在矩阵内部找到一个0时,

     则封闭岛屿count增加1,并将陆地0置为水域1,且将与之相连的岛屿置为水域1,遍历完count即为封闭岛屿的数量。

代码实现:

public class 统计封闭岛屿的数目 {

public static void main(String[] args) {
int[][] 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}};
System.out.println(closedIsland(grid));
}

public static int closedIsland(int[][] grid) {
int count = 0;
int lineLength = grid.length;
int columnLength = grid[0].length;

// 利用泛洪算法先将 i = 0, i = lineLength - 1, j = 0, j = columnLength - 1中与0相连的所有0都变成1,这样就可以保证内部为0起始的陆地肯定是封闭岛屿,避免内部以0起始的陆地与边界为0相连的陆地相连,这种情况不是封闭的岛屿。
for (int i = 0; i < lineLength; ++i) {
for (int j = 0; j < columnLength; ++j) {
if (isBoundary(i, j, lineLength, columnLength) && grid[i][j] == 0) {
floodFill(grid, i, j, lineLength, columnLength);
}
}
}

// 统计数组非边界内的非零值,并利用泛洪算法将与0相连的0全部置为1,则统计0开始的个数即为封闭岛屿。
for (int i = 0; i < lineLength; ++i) {
for (int j = 0; j < columnLength; ++j) {
if (grid[i][j] == 0) {
count++;
floodFill(grid, i, j, lineLength, columnLength);
}
}
}

return count;
}

public static boolean isBoundary(int i, int j, int lineLength, int columnLength) {
return i == 0 || i == lineLength - 1 || j == 0 || j == columnLength - 1;
}

public static void floodFill(int[][] grid, int i, int j, int lineLength, int columnLength) {
if (i < 0 || i >= lineLength || j < 0 || j >= columnLength || grid[i][j] != 0) {
return;
}
grid[i][j] = 1;
floodFill(grid, i - 1, j, lineLength, columnLength);
floodFill(grid, i + 1, j, lineLength, columnLength);
floodFill(grid, i, j - 1, lineLength, columnLength);
floodFill(grid, i, j + 1, lineLength, columnLength);
}
}
posted @ 2021-08-01 14:40  chengxingliu  阅读(102)  评论(0)    收藏  举报