算法打卡day2 (2026-02-07 周五) | 算法: DFS | 3_卡码网99_计数孤岛_DFS

- 第 162 篇 -
Date: 2026 - 02- 07
Author: 郑龙浩(仟墨)

2026-02-07 周五 | 算法打卡day2

文章目录

3_卡码网99_计数孤岛_DFS

算法: DFS

题目描述

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

输入描述

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

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

输出描述

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

输入示例

复制代码
4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

复制代码
3
cpp 复制代码
// Date: 2026-02-07 Author:郑龙浩

// 3_卡码99_计数孤岛_DFS.cpp

// DFS

// 用时: 60min

#include "bits/stdc++.h"

using namespace std;

  

int direction[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

  

// 写法1:显性终止条件(先判断坐标是否合理,后标记,再dfs搜索下一个坐标)

void dfs1(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    int height = grid.size(); // 高

    int width = grid[0].size(); // 宽

    if (x < 0 ||  x > height - 1 || y < 0 || y > width - 1)  return; // 如果越界,终止

    if (grid[x][y] == 0 || visited[x][y] == true) return; // 如果当前坐标 是海洋,或者访问过,终止

    visited[x][y] = true; // 将当前坐标标记为 已访问过

    // 只检查周围四个坐标点

    int nextX, nextY;

    for (int i = 0; i < 4; i ++) {

        nextX = x + direction[i][0];

        nextY = y + direction[i][1];

        dfs1(grid, visited, nextX, nextY); // 意思:用dfs深搜遍历 (nextX, nextY) 周围的四个点

    }

}

  

// 写法2:隐性终止条件(先标记,后面检查坐标,如果不合条件,是不会执行下一次的标记的,所以前面可以在不检查的条件下进行标记的操作)

void dfs2(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    int height = grid.size(); // 高

    int width = grid[0].size(); // 宽

  

    visited[x][y] = true; // 将当前坐标标记为 已访问过

  

    // 只检查周围四个坐标点

    int nextX, nextY;

    for (int i = 0; i < 4; i ++) {

        nextX = x + direction[i][0];

        nextY = y + direction[i][1];

        if (nextX < height && nextX >= 0 && nextY < width && nextY >= 0 && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) { // 如果下一个坐标没有越界且是陆地,且没有访问过,就用dfs深搜遍历它周围四个点

            dfs2(grid, visited, nextX, nextY);

        }

    }

}

  

int main(void) {

    ios::sync_with_stdio(0);

    cin.tie(0); cout.tie(0);

    int N, M, cnt = 0;

    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];

        }

    }

  

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            // 如果当前位置是陆地且未被访问,说明发现了一个新岛屿

            if (grid[i][j] == 1 && visited[i][j] == 0) {

                dfs2(grid, visited, i, j); // 通过DFS标记这个岛屿的所有相连陆地

                cnt ++; // 岛屿数量加1

            }

        }

    }

    cout << cnt;

    return 0;

}
相关推荐
TAN-90°-4 分钟前
Deep Learning for Computer Vision——Generative Models 2
人工智能·深度学习·神经网络·算法·目标检测·机器学习·计算机视觉
Rabitebla12 分钟前
【Linux系统编程】指令(三):创建、删除、复制、移动、看内容
linux·数据结构·c++·算法
qq_410194291 小时前
.NET 8.0 下基于 PaddleOCRSharp 的离线文字识别落地指南
算法·.net
Omics Pro1 小时前
1个月2轮融资!长寿虚拟细胞
数据库·人工智能·算法·机器学习·自然语言处理
residual_fan1 小时前
航空发动机故障诊断专用智能体(六):实际机队健康管理中的应用考量与展望
人工智能·算法·数据挖掘·数据分析
hansang_IR1 小时前
【讲解】CSP-S2026 第一轮初赛
c++·算法
hanlin031 小时前
刷题笔记:力扣第76题-最小覆盖子串
笔记·算法·leetcode
Zane19941 小时前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
tiger8651 小时前
大语言模型面试和题解,梳理中国主流开源 LLM 系列的发展脉络、技术路线与工程取舍
人工智能·gpt·深度学习·算法·自然语言处理·面试·transformer
我不会起名字3222 小时前
一天一道力扣Hot100(36):深度优先算法---组合总和
数据结构·c++·后端·python·算法·go