图-岛屿-dfs
前言
参考:https://mp.weixin.qq.com/s/IZQkb-M27dt-AZ1VICThOw
岛屿系列问题可以用 DFS/BFS 算法或者 Union-Find 并查集算法 来解决。
用 DFS 算法解决岛屿题目是最常见的,每次遇到一个岛屿中的陆地,就用 DFS 算法吧这个岛屿「淹掉」。
如何使用 DFS 算法遍历二维数组?你把二维数组中的每个格子看做「图」中的一个节点,这个节点和周围的四个节点连通,这样二维矩阵就被抽象成了一幅网状的「图」。
为什么每次遇到岛屿,都要用 DFS 算法把岛屿「淹了」呢?主要是为了省事,避免维护 visited 数组。
图算法遍历基础 说了,遍历图是需要 visited 数组记录遍历过的节点防止走回头路。
因为 dfs 函数遍历到值为 0 的位置会直接返回,所以只要把经过的位置都设置为 0,就可以起到不走回头路的作用。
PS:这类 DFS 算法还有个别名叫做 FloodFill 算法,现在有没有觉得 FloodFill 这个名字还挺贴切的~
200. 岛屿数量
https://leetcode.cn/problems/number-of-islands/description/?envType=study-plan-v2&envId=top-100-liked
// 详细解析参见:
https://labuladong.online/algo/slug.html?slug=number-of-islands
// 注意:cpp 代码由 chatGPT🤖 根据我的 java 代码翻译。
// 本代码的正确性已通过力扣验证,如有疑问,可以对照 java 代码查看。
class Solution {
public:
// 主函数,计算岛屿数量
int numIslands(vector<vector<char>>& grid) {
int res = 0;
int m = grid.size(), n = grid[0].size();
// 遍历 grid
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
// 每发现一个岛屿,岛屿数量加一
res++;
// 然后使用 DFS 将岛屿淹了
dfs(grid, i, j);
}
}
}
return res;
}
// 从 (i, j) 开始,将与之相邻的陆地都变成海水
void dfs(vector<vector<char>>& grid, int i, int j) {
int m = grid.size(), n = grid[0].size();
if (i < 0 || j < 0 || i >= m || j >= n) {
// 超出索引边界
return;
}
if (grid[i][j] == '0') {
// 已经是海水了
return;
}
// 将 (i, j) 变成海水
grid[i][j] = '0';
// 淹没上下左右的陆地
dfs(grid, i + 1, j);
dfs(grid, i, j + 1);
dfs(grid, i - 1, j);
dfs(grid, i, j - 1);
}
};
使用常规visit数组标识是否问过:
class Solution {
private:
public:
int numIslands(vector<vector<char>>& grid)
{
int m = grid.size(), n = grid[0].size();
int islands = 0;
vector<vector<bool>> visited(m, vector<bool>(n, false));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1' && !visited[i][j]) {
dfs(grid, i, j, visited);
islands++;
}
}
}
return islands;
}
void dfs(const vector<vector<char>>& grid, int i, int j, vector<vector<bool>>& visited)
{
int m = grid.size(), n = grid[0].size();
if (i < 0 || j < 0 || i >= m || j >= n) {
return;
}
if (visited[i][j] || grid[i][j] == '0') {
return;
}
visited[i][j] = true;
dfs(grid, i + 1, j, visited);
dfs(grid, i - 1, j, visited);
dfs(grid, i, j + 1, visited);
dfs(grid, i, j - 1, visited);
}
};