给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3






//章节 - 队列和栈    
//二、队列与广度优先搜索
//1.岛屿的个数
/*
算法思想:
    这是一道很有意思的题,本质是求矩阵中连续区域的个数,很容易想到需要用深度优先搜索DFS来解,需要建立一个visited数组用来记录某个位置是否被访问过,对于一个为‘1’且未被访问过的位置,递归进入其上下左右位置上为‘1’的数,将其visited对应值赋为true,继续进入其所有相连的邻位置,这样可以将这个连通区域所有的数找出来,并将其对应的visited中的值赋true,找完一次区域后,我们将结果res自增1,然后我们在继续找下一个为‘1’且未被访问过的位置,以此类推直至遍历完整个原数组即可得到最终结果。
*/
//算法实现:
class Solution {
public:
    int numIslands(vector<vector<char> > &grid) {
        if (grid.empty() || grid[0].empty())    //
            return 0;
        int m = grid.size(), n = grid[0].size(), res = 0;   //m行n列
        vector<vector<bool> > visited(m, vector<bool>(n, false));   //将二维数组初始为false,即都未访问
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '1' && !visited[i][j]) {  //为1且未被访问,则递归进入其上下左右位置上为‘1’的数
                    numIslandsDFS(grid, visited, i, j);
                    ++res;  //找完一次区域后,结果res自增1
                }
            }
        }
        return res;
    }
    void numIslandsDFS(vector<vector<char> > &grid, vector<vector<bool> > &visited, int x, int y) {
        if (x < 0 || x >= grid.size()) 
            return;
        if (y < 0 || y >= grid[0].size()) 
            return;
        if (grid[x][y] != '1' || visited[x][y])     //不为1或已被访问
            return;
        visited[x][y] = true;   //已访问
        numIslandsDFS(grid, visited, x - 1, y); //递归访问上位置
        numIslandsDFS(grid, visited, x + 1, y); //递归访问下位置
        numIslandsDFS(grid, visited, x, y - 1); //递归访问左位置
        numIslandsDFS(grid, visited, x, y + 1); //递归访问右位置
    }
};