给定一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
解法1:并查集 1578ms
class Solution {
private:
int num;
int* father = new int[100000000];
void init(int x) {
num = x;
for(int i = 1; i <= num; i++)
father[i] = i;
}
int find(int x) {
if(father[x] != x)
father[x] = find(father[x]);
return father[x];
}
void merge(int x, int y) {
int a = find(x);
int b = find(y);
if(a != b)
father[b] = a;
}
int getSubsetNum() {
int res = 0;
for(int i = 1; i <= num; i++)
if(father[i] == i)
res++;
return res;
}
public:
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
int n,m;
int icount=0;
int numIslands(vector<vector<char>>& grid) {
n=grid.size();
if(n==0) return 0;
m=grid[0].size();
int inum=0;
init(m*n);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++) {
if(grid[i][j]=='1') inum++;
else father[i*m+j+1]=-1;
}
for(int i=0; i<n; i++)
for(int j=0; j<m-1; j++) {
if(grid[i][j]=='1'&&grid[i][j+1]=='1')
merge(i*m+j+1,i*m+j+1+1);
}
for(int i=0; i<m; i++)
for(int j=0; j<n-1; j++) {
if(grid[j][i]=='1'&& grid[j+1][i]=='1')
merge(j*m+i+1,(j+1)*m+i+1);
}
//cout<<getSubsetNum()<<endl;
return getSubsetNum();
}
};
解法2 dfs 15ms
class Solution {
public:
int xx[4]= {1,-1,0,0};
int yy[4]= {0,0,1,-1};
int n,m;
int icount=0;
void dfs(int x,int y,vector< vector<bool> > &vist) {
vist[x][y]=true;
for(int k=0; k<4; k++) {
int nx=x+xx[k];
int ny=y+yy[k];
if(nx<0||nx>=n||ny<0||ny>=m)
continue;
if(!vist[nx][ny])
dfs(nx,ny,vist);
}
}
int numIslands(vector<vector<char>>& grid) {
n=grid.size();
if(n==0) return 0;
m=grid[0].size();
vector<bool> t(m,0);
vector< vector<bool> > vist(n,t);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++) {
if(grid[i][j]=='0') vist[i][j]=true;
}
for(int i=0; i<n; i++)
for(int j=0; j<m; j++) {
if(!vist[i][j]) {
icount++;
dfs(i,j,vist);
}
}
cout<<icount<<endl;
return icount;
}
};