一开始还以为会很难很难(以为暴力搜索会时间超限要用别的办法),没想到并不难。
我最开始是用vector<vector<bool>>记录搜索过的地域,每次递归遍历周围所有地域。
class Solution {
public:
vector<vector<char>> grid;
vector<vector<bool>> pass;
void spread(int i,int j,vector<vector<bool>>& pass){
if(i>=0&&j>=0&&grid.size()>i&&grid[0].size()>j&&grid[i][j]=='1'&&pass[i][j]==0) pass[i][j]=1;
else return;
spread(i+1,j,pass);
spread(i,j+1,pass);
spread(i-1,j,pass);
spread(i,j-1,pass);
}
int numIslands(vector<vector<char>>& grid) {
vector<vector<bool>> pass(grid.size(),vector<bool>(grid[0].size(),0));
this->pass=pass;
this->grid=grid;
int result=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(pass[i][j]==1||grid[i][j]=='0') continue;
else{
result++;
spread(i,j,pass);
}
}
}
return result;
}
};
后来想想可不可以直接修改原grid,这里出现了一个问题:
class Solution {
public:
vector<vector<char>> grid;
void spread(int i,int j){
if(i>=0&&j>=0&&grid.size()>i&&grid[0].size()>j&&grid[i][j]=='1') grid[i][j]='0';
else return;
spread(i+1,j);
spread(i,j+1);
spread(i-1,j);
spread(i,j-1);
}
int numIslands(vector<vector<char>>& grid) {
this->grid = grid;
int result=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]=='0') continue;
else{
result++;
spread(i,j);
}
}
}
return result;
}
};
出现的大问题就是我明明将grid设为了类里共有的存储,可是函数spread修改grid并没有修改到实际grid,问了ai也不知道为什么。
答案是直接将grid传入函数,还是没弄明白为什么this->grid=grid不管用了。总之按答案做就行了。
答案还有一种广度优先搜索,其实我觉得逻辑还是深度优先,就是和我原先的做法一样设置一个bool二维数组判断是否遍历过,然后没遍历一个没遍历过的点就压入队列,不断扩散直到队列为空(感觉就是dfs,不知道为什么叫做bfs…………)
所以就没有写了。
还有一种是并查集,大概是设置两个数组记录节点,一个记录父节点信息(每个岛屿最先遍历到的点的标识),一个记录岛屿的大小。一开始将每一个地块都记为一个父节点,岛屿大小都设为0,记录“岛屿”数量,然后慢慢遍历,在遍历的过程中将相邻的地块合并为一个并查集,记录值慢慢减小。