给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
这道题考察岛屿的个数,可以基于深度优先搜索或者广度优先搜索,或者并查集来做,这里提供两种解法。
采用DFS,对二维数组进行比遍历,遇到1
则找到一个岛屿,然后把与之关联的位置全部置为2
,那么对二维数组完成一次遍历,即可得出结果。代码如下:
class Solution {
public:
void setOne(vector<vector<char>> &grid,int row,int col){
int m=grid.size();
int n=grid[0].size();
if((row<0)||(row>=m)||(col<0)||(col>=n)||(grid[row][col]!='1')){
return;
}
grid[row][col]=2;
setOne(grid,row+1,col);
setOne(grid,row-1,col);
setOne(grid,row,col+1);
setOne(grid,row,col-1);
}
int numIslands(vector<vector<char>>& grid) {
int m=grid.size();
if(m==0) return 0;
int n=grid[0].size();
if(n==0) return 0;
int sum=0;
for(int i=0;ifor(int j=0;jif(grid[i][j]=='1'){
sum++;
setOne(grid,i,j);
}
}
}
return sum;
}
};
也可以考虑用并查集来做这题,将二维数组重新编号,从0
开始,从左到右,从上到下,直到n*m-1
(其中n
为行数,m
为列数),对于位置(i,j)
则编号为i*m+j
,那么相邻(左右,上下)的为同一个值,则认为他们相通。那么最终只要统计一下father[i]==i
且对应值为1
的个数即可。代码如下:
class Solution {
public:
int findFather(vector<int> &father,int a){
int f=a;
while(father[f]!=f){
f=father[f];
}
while(father[a]!=a){
int z=a;
a=father[z];
father[a]=f;
}
return f;
}
void unionFather(vector<int> &father, int a,int b){
int fa=findFather(father,a);
int fb=findFather(father,b);
if(fa!=fb){
father[fa]=fb;
}
}
int numIslands(vector<vector<char>>& grid) {
if(grid.size()==0||grid[0].size()==0) return 0;
int n=grid.size(),m=grid[0].size(),k=n*m;
vector<int> father(k,-1);
for(int i=0;ifor(int i=0;ifor(int j=0;jint t1=i*m+j;
int t2=t1+1,t3=t1+m;
if(j+11]) unionFather(father,t1,t2);
if(i+11][j]) unionFather(father,t1,t3);
}
}
int res=0;
for(int i=0;iif(father[i]==i&&grid[i/m][i%m]=='1'){
res+=1;
}
}
return res;
}
};