leetcode:1254. 统计封闭岛屿的数目
题目
二维矩阵 grid
由 0
(土地)和 1
(水)组成。岛是由最大的 4 个方向连通的 0
组成的群,封闭岛是一个 **完全**
由 1
包围(左、上、右、下)的岛。
请返回 封闭岛屿 的数目。
示例 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
解答 & 代码
[中等] 200. 岛屿数量
本题是统计封闭岛屿的数量,和上题的区别在于:
- 本题
0
表示陆地,1
表示海水,和上题相反 封闭岛屿是上下左右都被海水(
1
)包围的岛屿(0
),越界的地方不算海水(1
),因此靠边的陆地不算岛屿(而上题越界的地方认为是海水,因此靠边的陆地也算岛屿)。更具体地,将上题的岛屿中除去靠边的岛屿,剩下的就是封闭岛屿:若某个岛屿至少有一格在上、下、左、右任意一个边界上,这个岛屿就不是封闭岛屿。因为如果有一格在上边界上,它的上方就不是海水;如果有一格在下边界上,它的下方就不是海水;如果有一格在左边界上,它的左边就不是海水;如果有一格在右边界上,它的右边就不是海水
class Solution {
private:
// 深度优先搜索,从位置 (row, col) 开始,将与之相邻的都置 1(即变为海水)
void dfs(vector<vector<int>>& grid, int row, int col)
{
int rows = grid.size();
int cols = grid[0].size();
// 递归结束条件:越界 or 已经是海水
if(row < 0 || row >= rows || col < 0 || col >= cols || grid[row][col] == 1)
return;
// 将 (row, col) 位置置 1(即变为海水)
grid[row][col] = 1;
// 递归搜索上、下、左、右,将当前岛屿的每个位置都变为 1(即变为海水)
dfs(grid, row - 1, col);
dfs(grid, row + 1, col);
dfs(grid, row, col - 1);
dfs(grid, row, col + 1);
}
public:
int closedIsland(vector<vector<int>>& grid) {
if(grid.size() == 0 || grid[0].size() == 0)
return 0;
int rows = grid.size();
int cols = grid[0].size();
// 1. 去掉靠上、下、左、右边界的岛屿(置为 1,相当于淹掉)
for(int col = 0; col < cols; ++col)
{
dfs(grid, 0, col); // 靠上边界的岛屿淹掉(变为海水 1)
dfs(grid, rows - 1, col); // 靠下边界的岛屿淹掉(变为海水 1)
}
for(int row = 0; row < rows; ++row)
{
dfs(grid, row, 0); // 靠左边界的岛屿淹掉(变为海水 1)
dfs(grid, row, cols - 1); // 靠右边界的岛屿淹掉(变为海水 1)
}
// 2. 剩下的都是封闭岛屿,统计封闭岛屿个数
int islandCnt = 0;
for(int row = 1; row < rows - 1; ++row)
{
for(int col = 1; col < cols - 1; ++col)
{
if(grid[row][col] == 0)
{
++islandCnt;
dfs(grid, row, col);
}
}
}
return islandCnt;
}
};
复杂度分析:设矩阵 M 行 N 列
- 时间复杂度 O(MN)
- 空间复杂度 O(MN):在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 MN,即空间复杂度达到 O(MN)
执行结果:
执行结果:通过
执行用时:12 ms, 在所有 C++ 提交中击败了 61.37% 的用户
内存消耗:9.2 MB, 在所有 C++ 提交中击败了 61.56% 的用户