题目说明
200. 岛屿的个数:给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
**思路:**这种类型的问题学GIS图形算法的时候学过,当时用的时队列进行遍历,方法叫啥名字我忘了,反正莫名觉得这种问题挺经典,所以记录一下。分别为深度优先与广度优先。
广度优先搜索(BFS)
思路
广度优先搜索最经典的实现方法是使用队列进行实现,本题也不例外。为了方便之后的处理,构建一个结构体用于存储相应坐标,之后的过程主要就是数组越界判断以及岛屿判断了,结合队列的出与进进行“广度遍历”并把已经到过的地方做上标记(即下面的flag数组)。
本题要注意的还有就是题干给的是char类型的1与0,不要想成int了。。。
AC代码
struct node{
int x,y;
};
int numIslands(vector<vector<char>>& grid) {
if(grid.size()==0||grid[0].size()==0)
return 0;
int m=grid.size(),n=grid[0].size();
int res=0;
vector<vector<int> > flag(m,vector<int>(n,0));//0 no visit
int directX[4]={-1,1,0,0};
int directY[4]={0,0,-1,1};
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]=='0'||flag[i][j]==1)
continue;
res++;
node first;
first.x=i,first.y=j;
queue<node> q;
q.push(first);
while(!q.empty()){
node top=q.front();
q.pop();
for(int k=0;k<4;k++){
int X=top.x+directX[k];
int Y=top.y+directY[k];
if(X>=m||X<0||Y>=n||Y<0||grid[X][Y]=='0'||flag[X][Y]==1)
continue;
flag[X][Y]=1;
node New;
New.x=X,New.y=Y;
q.push(New);
}
}
}
}
return res;
}
深度优先搜索(DFS)
思路
广度优先搜索主要是递归实现(也可以理解成栈)。同时我发现以上所述的那个“标记矩阵”没必要建立,只需把题目中访问过的陆地改成水即可(‘0’),算是该题目的一个小技巧吧,AC代码如下。
AC代码
int numIslands(vector<vector<char>>& grid) {
if(grid.empty()||grid[0].empty())
return 0;
int m=grid.size(),n=grid[0].size();
int res=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]=='1'){
res++;
DFS(grid,i,j);
}
}
}
return res;
}
void DFS(vector<vector<char>>& grid,int row,int col){
int m=grid.size(),n=grid[0].size();
if(row<0||row>=m||col<0||col>=n||grid[row][col]=='0')
return;
grid[row][col]='0';
DFS(grid,row-1,col);
DFS(grid,row+1,col);
DFS(grid,row,col-1);
DFS(grid,row,col+1);
}