题目描述
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例:
输入:
11000
11000
00100
00011
输出: 3
解题思路:DFS,BFS都行
-
DFS:遍历岛这个二维数组,如果当前数为1,则进入感染函数并将岛个数+1。
感染函数:其实就是一个递归标注的过程,它会将所有相连的1都标注成2。为什么要标注?这样就避免了遍历过程中的重复计数的情况,一个岛所有的1都变成了2后,遍历的时候就不会重复遍历了。(还省下了
visited[][]/marked[][]
数组的空间)class Solution { public int numIslands(char[][] grid) { int islandNum = 0; for(int i = 0; i < grid.length; i++){ for(int j = 0; j < grid[0].length; j++){ if(grid[i][j] == '1'){ infect(grid, i, j); islandNum++; } } } return islandNum; } //感染函数 public void infect(char[][] grid, int i, int j){ if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != '1'){ return; } grid[i][j] = '2'; infect(grid, i + 1, j); infect(grid, i - 1, j); infect(grid, i, j + 1); infect(grid, i, j - 1); } }
-
BFS(BFS和DFS都巨清晰,大佬文章):注意如果等到元素出队的时候才标记 “已经访问”,事实上,这种做法是错误的。因为如果不在刚刚入队列的时候就标记 “已经访问”,相同的结点很可能会重复入队。
参考代码
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int rows = grid.size();
if(rows == 0)
return 0;
int cols = grid[0].size();
int res = 0;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(grid[i][j] == '1'){
res++;
infect(grid, i, j, rows, cols);
}
}
}
return res;
}
// dfs
void infect(vector<vector<char>>& grid, int i, int j, int rows, int cols){
if(i < 0 || i >= rows || j < 0 || j >= cols || grid[i][j] != '1')
return;
grid[i][j] = 2;
infect(grid, i+1, j, rows, cols);
infect(grid, i-1, j, rows, cols);
infect(grid, i, j+1, rows, cols);
infect(grid, i, j-1, rows, cols);
}
};