方法一:DFS(深度优先搜索)

 深度优先搜索一般用于树或者图的遍历,其他有分支的(如二维矩阵)也适用。它的原理是从初始点开始,一直沿着同一个分支遍历,直到该分支结束,然后回溯到上一级继续沿着一个分支走到底,如此往复,直到所有的节点都有被访问到。

使用深度优先搜索(dfs):遍历矩阵,当遇到矩阵的某个元素为1时,首先将其置为了0,然后查看与它相邻的上下左右四个方向,如果这四个方向任意相邻元素为1,则进入该元素,进入该元素之后我们发现又回到了刚刚的子问题,又是把这一片相邻区域的1全部置为0,可以用递归实现。这样就将一个岛全部置0了。继续向下遍历矩阵重新进入上述的case。

时间复杂度:o(nm)。n、m为矩阵的行数和列数

空间复杂度:o(nm)。n、m为矩阵的行数和列数

class Solution {
public:
    int solve(vector<vector<char> >& grid) {
        int n = grid.size();     //行数
        int m = grid[0].size();  //列数
		//特殊情况处理(空矩阵)
        if(n == 0)
            return 0;
        
        int count = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(grid[i][j] == '1') {
                    count++;
					//广度优先搜索
                    dfs(grid, i, j, n, m);
                }
            }
        }

        return count;
    }
private:
    void dfs(vector<vector<char> >& grid, int row, int col, int maxRow, int maxCol) {
        grid[row][col] = '0';
        //上方
        if(grid[row - 1][col] == '1' && row > 0)
            dfs(grid, row - 1, col, maxRow, maxCol);
        //下方
        if(grid[row + 1][col] == '1' && row + 1 < maxRow)
            dfs(grid, row + 1, col, maxRow, maxCol);
        //左侧
        if(grid[row][col - 1] == '1' && col > 0)
            dfs(grid, row, col - 1, maxRow, maxCol);
        //右侧
        if(grid[row][col + 1] == '1' && col + 1 < maxCol)
            dfs(grid, row, col + 1, maxRow, maxCol);
        
        return;
    }
};

方法二:BFS(广度优先搜索)

广度优先搜索与深度优先搜索不同,它是将与某个节点直接相连的其它所有节点依次访问一次之后,再往更深处,进入与其他节点直接相连的节点。bfs的时候我们常常会借助队列的先进先出,因为从某个节点出发,我们将与它直接相连的节点都加入队列,它们优先进入,则会优先弹出,在它们弹出的时候再将与它们直接相连的节点加入,由此就可以依次按层访问。

思路:

统计岛屿的方法可以和方法一同样遍历解决,为了去重我们还是要将所有相邻的1一起改成0,这时候同样遍历连通的广度优先搜索(bfs)可以代替dfs。

具体做法:

  • step 1:优先判断空矩阵等情况。
  • step 2:从上到下从左到右遍历矩阵每一个位置的元素,如果该元素值为1,统计岛屿数量。
  • step 3:使用bfs将遍历矩阵遇到的1以及相邻的1全部置为0:利用两个队列辅助(C++可以使用pair),每次队列进入第一个进入的1,然后遍历队列,依次探讨队首的四个方向,是否符合,如果符合则置为0,且位置坐标加入队列,继续遍历,直到队列为空。

时间复杂度:o(nm)。n、m为矩阵的行数和列数

空间复杂度:o(nm)。n、m为矩阵的行数和列数

class Solution {
  public:
    int solve(vector<vector<char> >& grid) {
        int n = grid.size();     //行数
        int m = grid[0].size();  //列数
		//特殊情况处理(空矩阵)
        if (n == 0)
            return 0;

        int count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '1') {
                    count++;
                    pos_x.push(i);
                    pos_y.push(j);
                    grid[i][j] = '0';
                    // 广度优先搜索
                    while (!pos_x.empty() && !pos_y.empty()) {
                        int length = pos_x.size();
                        for (int i = 0; i < length; i++) {
                            int row = pos_x.front();
                            pos_x.pop();
                            int col = pos_y.front();
                            pos_y.pop();
                            //上方
                            if (grid[row - 1][col] == '1' && row > 0) {
                                pos_x.push(row - 1);
                                pos_y.push(col);
                                grid[row - 1][col] = '0';
                            }
                            //下方
                            if (grid[row + 1][col] == '1' && row + 1 < n) {
                                pos_x.push(row + 1);
                                pos_y.push(col);
                                grid[row + 1][col] = '0';
                            }
                            //左侧
                            if (grid[row][col - 1] == '1' && col > 0) {
                                pos_x.push(row);
                                pos_y.push(col - 1);
                                grid[row][col - 1] = '0';
                            }
                            //右侧
                            if (grid[row][col + 1] == '1' && col + 1 < m) {
                                pos_x.push(row);
                                pos_y.push(col + 1);
                                grid[row][col + 1] = '0';
                            }
                        }
                    }
                }
            }
        }

        return count;
    }
  private:
    queue<int> pos_x;
    queue<int> pos_y;
};