问题描述:
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。
对于网格类遍历问题,深度优先搜索dfs是一种典型的解决方案,类比于二叉树的DFS,其程序框架如下:
void dfs(TreeNode* node){
if(node == NULL)
return;
dfs(node->left);
dfs(node->right);
}
程序的思想是:(1)先判断一下当前结点是否为空,即判断当前探索位置的有效性,(2)如果通过有效性判断,则递归遍历当前结点的孩子结点,或称连通结点,进行结点探索。
二叉树可以看作是一种简单的无环的图结构,对于网格问题,其实是一种复杂的图结构,其dfs遍历的思想框架与二叉树其实是一致的,dfs流程同样是先判断,在递归遍历:
(1)判断条件:当前位置是否越界(网格通常是有边界限制的);判断当前结点是否满足题目限制(如陆地为1)
(2)递归遍历:通常遍历当前位置的“ 上、下、左、右” 四个位置。
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int nr = grid.size();
if (!nr) return 0;
int nc = grid[0].size();
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
dfs(grid, r, c);
}
}
}
return num_islands;
}
private:
void dfs(vector<vector<char>>& grid, int r, int c) {
if (!inArea(grid, r, c))
return;
if(grid[r][c]!='1')
return;
grid[r][c] = '0';
dfs(grid, r - 1, c);
dfs(grid, r + 1, c);
dfs(grid, r, c - 1);
dfs(grid, r, c + 1);
}
bool inArea(vector<vector<char>>& grid, int r, int c) {
return 0 <= r && r < grid.size() && 0 <= c && c < grid[0].size();
}
};