题目描述
题目分析
题中的目标是求由1组成的岛屿有几个,先观察便界条件:当某个1的四周均为0时,或到达边界时,即为一个岛屿。可以使用BFS和DFS两种方式进行搜索,被搜索过的岛屿标记为“2”,不标记为“0”便于区分。
参考文章:岛屿数量
参考文章:岛屿数量(dfs+并查集详解)
参考文章:200. 岛屿数量(DFS+BFS)
DFS解法
DFS为深度优先遍历算法:
首先,确定好开始起点后,按一定规则顺序从四周选择方向,当选择的方向符合某一条件后,就依照该方向进行延伸选择结点,将选择的结点再为新一轮起点依照之前定义的规则顺序再从四周选择方向,以此类推,直到到达边界条件后,退回一步,按照上述选择四周的规则选择下一个方向,直至完成全图的扫描。
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
if(grid.size() == 0) return 0;
int row = grid.size(), col = grid[0].size(), count = 0;
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
if(grid[i][j] == '1'){
count++;
DFS(grid, i, j);
}
}
}
return count;
}
void DFS(vector<vector<char>>& grid, int i, int j){
//注意一定要先判断inArea才能再grid[i][j]是否为1
if(inArea(i, j, grid.size(), grid[0].size()) && grid[i][j] == '1'){
grid[i][j] = '2';
DFS(grid, i, j+1);
DFS(grid, i+1, j);
DFS(grid, i, j-1);
DFS(grid, i-1, j);
}
}
bool inArea(int i, int j, int row, int col){
return (i>=0)&&(i<row)&&(j>=0)&&(j<col);
}
};
时间复杂度为O(M * N),空间复杂度为O(M * N),其中M为行数,N为列数。
BFS解法
BFS为广度优先搜索算法:
首先,确定开始起点,然后按照一定规则顺序先遍历起点四周的各点,被遍历到的点若符合某一条件,在起点的四周遍历完后,将会依次按上述规则顺序对之前被遍历的符合条件的点的四周进行依次遍历。以此类推,直至扫描完全图后为止。
class Solution{
public:
int numIslands(vector<vector<char>>& grid){
if(grid.size() == 0) return 0;
int count = 0;
for(int i = 0; i < grid.size(); i++){
for(int j = 0; j < grid[0].size(); j++){
if(grid[i][j] == '1'){
count++;
grid[i][j] = '2';
BFS(grid, i, j);
}
}
}
return count;
}
void BFS(vector<vector<char>>& grid, int i, int j){
queue<pair<int,int>> q;
q.push({i, j});
while(!q.empty()){
auto cur = q.front(); q.pop();
int x = cur.first, y = cur.second;
if(y + 1 < grid[0].size() && grid[x][y+1] == '1'){
q.push({x, y+1});
grid[x][y+1] = '2';
}
if(x + 1 < grid.size() && grid[x+1][y] == '1'){
q.push({x+1, y});
grid[x+1][y] = '2';
}
if(y - 1 >= 0 && grid[x][y-1] == '1'){
q.push({x, y-1});
grid[x][y-1] = '2';
}
if(x - 1 >= 0 && grid[x-1][y] == '1'){
q.push({x-1, y});
grid[x-1][y] = '2';
}
}
}
};
时间复杂度为O(M * N),空间复杂度为O(min(M, N)),其中M为行数,N为列数。在最坏情况下,整个网格均为陆地,队列的大小可以达到 min(M,N)。