题目描述(中等难度)
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
解法一 拓展法(DFS)
思路:
想法很简单,我们只需要遍历二维数组,然后遇到 的时候,把当前的 以及它周围的所有 都标记成一个字符,这里直接标记成 。然后记录遇到了几次 ,就代表有几个岛屿
还有一个问题就是怎么标记与当前 相邻的 。也很直接,我们直接把和当前 连通的位置看做一个图,然后做一个遍历即可。可以直接用递归写一个 ,即深度优先遍历。DFS
public int numIslands(char[][] grid) {
//判断该网格是否存在,不存在就是0个岛屿
if (grid == null || grid.length == 0){
return 0;
}
//初始化结果(岛屿)的数量
int result = 0;
int row = grid.length;
int col = grid[0].length;
//遍历每一个格子
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1'){
result++;
//寻找'1'(陆地),并且把'1'及其周围改为'0'
dfs(grid,i,j,row,col);
}
}
}
return result;
}
private void dfs(char[][] grid, int x, int y, int row, int col) {
//如果超出边界或该格子是水域则跳出循环
if (x<0 || y<0 || x>= row || y>= col || grid[x][y] == '0'){
return;
}
//把该格子变为'0'(水域)
grid[x][y] = '0';
//向上下左右扩展
dfs(grid, x-1, y, row, col);
dfs(grid, x+1, y, row, col);
dfs(grid, x, y-1, row, col);
dfs(grid, x, y+1, row, col);
}
解法二 BFS
思路:
当然做遍历的话,我们也可以采用,广度优先遍历。图的广度优先遍历和二叉树的层次遍历类似,只需要借助一个队列即可。BFS
和上边的区别不大,改一下标记函数即可。
此外入队列的时候,我们把二维坐标转为了一维,就省去了再创建一个类表示坐标。
public int numIslands2(char[][] grid) {
if (grid == null || grid.length == 0){
return 0;
}
int result = 0;
int row = grid.length;
int col = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1'){
result++;
queue.add(new int[]{i,j});
grid[i][j] = '0';
//while循环寻找这个'1'(陆地)周围的所有'1'
while (queue.size()>0){
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
//>=0,是判断是否出界
if (x-1 >= 0 && grid[x-1][y] == '1'){
queue.add(new int[]{x-1,y});
grid[x-1][y] = '0';
}
if (y-1 >= 0 && grid[x][y-1]=='1'){
queue.add(new int[]{x,y-1});
grid[x][y-1]='0';
}
//注意这里是 < 不是<=
if(x+1 < row && grid[x+1][y] == '1'){
queue.add(new int[]{x+1,y});
grid[x+1][y] = '0';
}
if(y+1 < col && grid[x][y+1] == '1'){
queue.add(new int[]{x,y+1});
grid[x][y+1] = '0';
}
}
}
}
}
return result;
}