200. 岛屿数量
给你一个由 ‘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
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
题解:
我们可以将求解岛屿数量看成求解被同一个母体感染源感染的区域数量。
- 遍历grid数组,一旦遍历到一个元素为‘1’,则对其向上下左右四个方向“感染”,且如果被“感染”的位置本来元素值为‘1’,则认为是感染成功,所以‘1’改为‘2’;若本来被“感染”的位置本来元素值为‘0’,则认为感染失败,所以‘0’不会改变。依照此思路进行深搜即可,注意边界问题即深搜结束条件即可。
注意的是,我们为什么要对“感染”成功的进行修改值呢?
- 因为我们不想让岛屿数量重复计算,即通过感染后修改值,使得遍历时不会再进行“重复感染”了,因为已经认为其感染过了。
另外有人会想,为什么要向四个方向感染呢?直接向右和向下感染好像就足够了啊!
反例:
["2","2","2"]
["0","2","0"]
["1","2","2"]
- 这时发现感染到最后左边的1会重复计算,但其实其是属于同一个母体感染源感染的!
- 并且还要注意的是在dfs方法中的if判断中,最后一个判断必须要为
grid[i][j]!='1'
!!!因为由于“感染”,导致被感染的‘1’都变成‘2’了,因此若碰到‘2’也是要停止的,因为这是已经感染过的,所以如果if中的判断只为grid[i][j]!='0'
,那么‘2’会重复计算。
代码:
class Solution {
public int numIslands(char[][] grid) {
int res = 0;
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
if(grid[i][j]=='1'){
dfs(grid,i,j);
res++;
}
}
}
return res;
}
public void dfs(char[][] grid,int i,int j){
if(i<0 || j<0 ||
i>grid.length-1 || j>grid[0].length-1 || grid[i][j]!='1'){
return;
}
grid[i][j] = '2';
dfs(grid,i+1,j);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i,j-1);
}
}