代码随想录算法训练营 Day51 图论Ⅱ岛屿问题Ⅰ

图论

题目

99. 岛屿数量

使用 DFS 实现方法

判断岛屿方法

  1. 遍历图,若遍历到了陆地 grid[i][j] = 1 并且陆地没有被访问,在这个陆地的基础上进行 DFS 方法,或者是 BFS 方法

  2. 对陆地进行 DFS 的时候时刻注意以访问的元素添加访问标记

cpp 复制代码
// DFS方法1
#include <iostream>
#include <vector>

int dir[4][2] = {0,1,1,0,-1,0,0,-1};
void dfs(std::vector<std::vector<int>>& grid, std::vector<std::vector<bool>>& vis, int x, int y) {
    // 从四个方向进行搜索
    for (int i = 0; i < 4; ++i) {
        int nexti = x + dir[i][0];
        int nextj = y + dir[i][1];
        // 边界情况判定
        if (nexti < 0 || nexti >= grid.size()
         || nextj < 0 || nextj >= grid[0].size()) continue;
        // 访问情况判定
        if (!vis[nexti][nextj] && grid[nexti][nextj] == 1) {
            // 时刻注意访问标记
            vis[nexti][nextj] = true;
            dfs(grid, vis, nexti, nextj);
        }
    }
}

int main() {
    // 输入处理
    int n, m, res = 0;
    std::cin >> n >> m;
    std::vector<std::vector<int>> grid(n, std::vector<int>(m, 0));
    std::vector<std::vector<bool>> vis(n, std::vector<bool>(m, false));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            std::cin >> grid[i][j];
        }
    }
    // 遍历网格进行DFS操作
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            // 访问到新陆地对该陆地进行遍历
            if (grid[i][j] == 1 && !vis[i][j]) {
                res++; // 记录新大陆
                vis[i][j] = true;
                dfs(grid, vis, i, j);
            }
        }
    }

    // 输出处理
    std::cout << res << std::endl;
}


// dfs 三部曲写法
#include <iostream>
#include <vector>
using namespace std;

int dir[4][2] = {0,-1,-1,0,1,0,0,1}; // 逆时针顺序
// 第一步参数与返回值
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 第二部 终止条件
    if (vis[x][y] || grid[x][y] == 0) return;
    // 第三部 单层递归逻辑
    vis[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(grid, vis, nextX, nextY);
    }
}

int main() {
    int n, m, res = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(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 (!vis[i][j] && grid[i][j] == 1) {
                res++;
                dfs(grid, vis, i, j);
            }
        }
    }

    cout << res << endl;
}

使用广度优先搜索方法

主函数部分不变,调用变成广度优先搜索

广度优先搜索保证入队列的时候就对数据做标记为访问

如果在取出队列时候标记会导致大量重复元素入队!

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int dir[4][2] = {0,-1,-1,0,1,0,0,1};
void bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 创建队列存储下标
    queue<pair<int, int>> que;
    // 保证入队的时候就标记访问防止重复访问
    que.push(make_pair(x, y));
    while (!que.empty()) {
        pair<int, int> cur = que.front();
        que.pop();
        for (int i = 0; i < 4; ++i) {
            int nextX = cur.first + dir[i][0];
            int nextY = cur.second + dir[i][1];
            if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
            if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
                que.push({nextX, nextY});
                vis[nextX][nextY] = true; // 入队即标记防止重复
            }
        }
    }
}

int main() {
    int n, m, res = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(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 (!vis[i][j] && grid[i][j] == 1) {
                res++;
                bfs(grid, vis, i, j);
            }
        }
    }

    cout << res << endl;
}

100. 岛屿的最大面积

岛屿最大面积,给出广度优先搜索,深度优先搜索(A 和 B)

深度优先 B广度优先在函数外初始化记录,深度优先 A 在函数内初始化记录

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

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

int bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    tmp = 1;
    queue<pair<int, int>> que;
    que.push(make_pair(x, y));
    vis[x][y] = true;
    while (!que.empty()) {
        pair<int, int> cur = que.front();
        que.pop();
        for (int i = 0; i < 4; ++i) {
            int nextX = cur.first + dir[i][0];
            int nextY = cur.second + dir[i][1];
            if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
            if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
                tmp++;
                que.push({nextX, nextY});
                vis[nextX][nextY] = true;
            }
        }
    }
    return tmp;
}

void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 1 fin
    if (vis[x][y] || grid[x][y] == 0) return;
    vis[x][y] = true;
    tmp++;
    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(grid, vis, nextX, nextY);
    }
}

void dfs2(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 2
    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;
        if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
            tmp++;
            vis[nextX][nextY] = true;
            dfs2(grid, vis, nextX, nextY);
        }
    }
}


int main(){
    int n, m, res = 0, maxV = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(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 (!vis[i][j] && grid[i][j] == 1) {
                res++;
                // 深度优先 1
                // tmp = 0; // 因为dfs内首先计算tmp
                // dfs(grid, vis, i, j);
                // maxV = max(maxV, tmp);
                // 深度优先 2
                tmp = 1; // dfs需要初始
                vis[i][j] = true;
                dfs2(grid, vis, i, j);
                maxV = max(maxV, tmp);
                // 广度优先
                // maxV = max(maxV, bfs(grid, vis, i, j));
            }
        }
    }
    // cout << "res" << res << endl;
    cout << maxV << endl;
    return 0;
}
相关推荐
顾子茵9 分钟前
游戏开发实战(一):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所---源码级解析该小游戏背后的算法与设计模式【纯原创】
python·算法·游戏
被AI抢饭碗的人1 小时前
算法题(150):拼数
数据结构·算法
知识漫步1 小时前
代码随想录算法训练营第60期第三十九天打卡
算法
June`1 小时前
专题五:floodfill算法(太平洋大西洋水流问题)
c++·算法·leetcode·深度优先·剪枝
爱吃涮毛肚的肥肥(暂时吃不了版)2 小时前
仿腾讯会议——添加音频
c++·算法·面试·职场和发展·音视频·腾讯会议
梁辰兴2 小时前
数据结构实验10.1:内部排序的基本运算
数据结构·c++·算法·排序算法·c·内部排序
exe4523 小时前
力扣每日一题5-19
java·算法·leetcode
fouen3 小时前
【语义分割专栏】先导篇:评价指标(PA,CPA,IoU,mIoU,FWIoU,F1)
人工智能·算法·机器学习·计算机视觉
zbh06043 小时前
AcWing 223. 阿九大战朱最学——扩展欧几里得算法
算法
mochensage4 小时前
2025年全国青少年信息素养大赛C++小学全年级初赛试题
开发语言·c++·算法