代码随想录|图论|05岛屿数量(深搜DFS)

发布于:2025-06-27 ⋅ 阅读:(13) ⋅ 点赞:(0)

leetcode:99. 岛屿数量

题目

题目描述:

给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述:

第一行包含两个整数 N, M,表示矩阵的行数和列数。

后续 N 行,每行包含 M 个数字,数字为 1 或者 0。

输出描述:

输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。

思路

遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上(这一步就是为了防止重复计算!)。

在遇到标记过的陆地节点和海洋节点的时候直接跳过.

计数器就是最终岛屿的数量。

下面代码详细注释:

#include <bits/stdc++.h>
using namespace std;

// 定义4个方向
int dir[4][2] = {1, 0, 0, -1, -1, 0, 0, 1};

void dfs(vector<vector<int>> &grid, vector<vector<bool>> &visited, int x, int y)
{
    // 终止条件:如果遇到海水或者已经遍历过的岛屿就停下来
    if (grid[x][y] == 0 || visited[x][y])
    {
        return;
    }
    // 处理当前节点:当前到了(x,y)这个点,首先就把它标记上
    visited[x][y] = true;
    // 当前节点往下延伸,看它四周的点
    for (int i = 0; i < 4; i++)
    {
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        // 基本限制条件:下一个点肯定不能跑到整个大矩阵的外面去
        if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size())
            continue;
        // 递归:这里递归不需要任何条件,因为一进入dfs就会有终止条件来判断
        dfs(grid, visited, nextx, nexty);
    }
}

int main()
{
    int n, m;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> grid[i][j];
        }
    }
    // count最终岛屿计数
    int count = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            // 一个一个陆地开始找,不要觉得麻烦,因为有的陆地已经被标记了,就会直接跳过
            if (grid[i][j] == 1 && !visited[i][j])
            {
                count++;
                dfs(grid, visited, i, j);
            }
        }
    }
    cout << count << endl;
    return 0;
}

一定要清楚dfs在这里的作用:

对(x,y)周围的岛屿进行标记! 

总结

我这里写的是dfs的第二个模板,第一个模版因为没有终止条件,所以写起来感觉很奇怪,我就没有放,感兴趣去看随想录。

参考资料

代码随想录