给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:
[
[‘1’,‘1’,‘1’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘0’,‘0’]
]
输出: 1
示例 2:
输入:
[
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘1’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘1’,‘1’]
]
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/queue-stack/kbcqv/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我们的目标是找出二维网格中的岛屿数量。因此,当我们遍历搜索二维网格,一旦发现当前顶点属于陆地时,就发现新岛屿,岛屿的数量将会加一,并且将该陆地顶点作为探索当前岛屿的全部陆地的搜索起点。
这里采用广度优先搜索的方式去探索当前岛屿的全部陆地。广度优先搜索首先会搜索与当前陆地距离为1的顶点(即相连的水平和垂直方向的四个顶点)是否为陆地,然后才去探索距离为2的顶点是否为陆地,就这样依次搜索下去, 直至无法搜索到新的陆地时搜索结束,则岛屿的全部陆地探索完毕。
同时,只要还有二维网格中的顶点未被搜索,则继续进行上述的广度优先搜索过程,直至全部顶点都被探索。
class Solution {
queue> que;
vector> visited;
public:
int numIslands(vector>& grid) {
if (grid.empty()) {
return 0;
}
int rows = grid.size();
int cols = grid[0].size();
visited = vector>(rows, vector(cols, false));
int ans = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == '1' and !visited[i][j]) {
//发现新的岛屿
visited[i][j] = true;
ans++;//岛屿数量加一
//利用广度优先搜索,找出这座岛屿的全部顶点,并标记为已搜索状态
que.push(make_pair(i, j));
while (!que.empty()) {
auto pair = que.front();
que.pop();
int r = pair.first;
int c = pair.second;
if (r - 1 >= 0 and !visited[r-1][c] and grid[r-1][c] == '1') {
visited[r-1][c] = true;
que.push(make_pair(r-1, c));
}
if (r + 1 < rows and !visited[r+1][c] and grid[r+1][c] == '1') {
visited[r+1][c] = true;
que.push(make_pair(r+1, c));
}
if (c - 1 >= 0 and !visited[r][c-1] and grid[r][c-1] == '1') {
visited[r][c-1] = true;
que.push(make_pair(r, c-1));
}
if (c + 1 < cols and !visited[r][c+1] and grid[r][c+1] == '1') {
visited[r][c+1] = true;
que.push(make_pair(r, c+1));
}
}
} else {
//顶点已完成搜索,或顶点是水
visited[i][j] = true;
}
}
}
return ans;
}
};