代码随想录算法训练营第60期第五十五天打卡

news2025/6/6 11:42:33

        大家好,我们今天继续我们图论的部分,其实我们昨天是主要讲解了深搜与广搜的理论基础,我们大体上了解了两种算法的差异与适用情景,今天我们就继续我们的图论的章节,以后几天的题目是图论中比较有名的问题叫做岛屿问题,我们就开始今天的题目。

第一题对应卡码网编号为99的题目岛屿数量

       这是我们岛屿问题里面的第一题,我们是需要求岛屿的数量,我们还是先来看一下这道题目的题目要求:

        大家看我们题目给出的地图就可以了解什么样的陆地才可以叫做岛屿,首先要是水平方向或者垂直方向上相邻,但注意斜方向的不算,就比如说我们题目给出的地图很明显左上方的可以是一个岛屿,右下方的也可以是岛屿,当然中间由于跟两个岛屿是斜着连接的所以只能单独算作一个岛屿,因此我们这道题也是很适合使用深搜来解决,我们就搜索四个方向,当然要保证当前的节点没有被访问过,一个节点肯定只能属于一个岛屿,总不能一个节点既属于一个岛屿又属于另一个岛屿,还有一点大家需要注意我们搜索的过程中千万不可以超出地图的边界,因此我们可以尝试写出深搜的代码:

#include <iostream>
#include <vector>
using namespace std;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};//方向数组表示上下左右四个方向
void dfs(const vector<vector<int>>&grid,vector<vector<bool>>&visited,int x,int y)
{
    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 (!visited[nextx][nexty] && grid[nextx][nexty])
        {
            visited[nextx][nexty] = true;
            dfs(grid, visited, nextx, nexty);
        }
    }
    return;
}
int main()
{
    int n, m; cin >> n >> m;
    vector<vector<int>> grid(n + 1, vector<int>(m + 1, 0));
    vector<vector<bool>> visited(n + 1, vector<bool>(m + 1, 0));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j) cin >> grid[i][j];
    }
    int count = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j) 
        {
            if (!visited[i][j] && grid[i][j])
            {
                visited[i][j] = true;
                count++;
                dfs(grid, visited, i, j);
            }
        }
    }
    cout << count << '\n';
    return 0;
}

        当然上面是深搜的写法,那这道题目可以使用广搜的写法吗?是可以的,我们依旧可以通过广搜的写法来解决这道题目,只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过。这个要注意我们广搜非常重要的点,我们广搜是借助队列来搜索的,我们只要加入队列就立马标记,这就表示我们已经访问过了这个陆地,那这样的话根据我们广搜的模板与对题目的理解我们就可以尝试给出广搜的代码:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void bfs(const vector<vector<int>>&grid,vector<vector<bool>>&visited,int x,int y)
{
    //定义队列
    queue<pair<int, int>> que;
    //将起点添加到队列里面
    que.push({x, y});
    visited[x][y] = true; //只要加入队列立刻标记
    while(!que.empty())
    {
        pair<int, int> cur = que.front(); que.pop();
        int curx = cur.first;
        int cury = cur.second;
        for (int i = 0; i < 4; ++i)
        {
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1];
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty>=grid[0].size()) continue; //超出边界的部分去掉
            if (!visited[nextx][nexty] && grid[nextx][nexty])
            {
                que.push({nextx,nexty});
                visited[nextx][nexty] = true;
            }
        }
    }
}

int main()
{
    int n,m; cin >> n >> m;
    vector<vector<int>> grid(n + 1, vector<int>(m + 1, 0));
    vector<vector<bool>> visited(n + 1, vector<bool>(m + 1, false));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j) cin >> grid[i][j];
    }
    //存储岛屿的数量
    int result = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (!visited[i][j] && grid[i][j])
            {
                result++;
                bfs(grid, visited, i, j);
            }
        }
    }
    cout << result << '\n';
    return 0;
}

       这个是广搜的代码,其实跟我们上次的广搜模板是一样的,以后的题目我主要只给深搜的代码,我尽力也给广搜的代码,我个人的话还是深搜用的多一些,请大家见谅!

第二题对应卡码网编号为100的题目岛屿的最大面积

        这是我们今天的第二题,我们这道题目其实跟上一道题的思路是很相似的,不过是上一道题目要求我们去找岛屿的数量而这道题则是求最大岛屿的面积,其实这道题我还是使用深搜来解决,我们其实就是不断更新岛屿面积不就可以了,其实不算难,前提是大家掌握清楚上一道题目的思路,我们还是使用深度优先搜索来给大家解决这道题目:

#include <iostream>
#include <vector>

using namespace std;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int count;
void dfs(const vector<vector<int>> &grid, vector<vector<bool>> &visited, int x, int y)
{
    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 (!visited[nextx][nexty] && grid[nextx][nexty])
        {
            count++;
            visited[nextx][nexty] = true;
            dfs(grid, visited, nextx, nexty);
        }
    }
}

int main()
{
    int n, m; cin >> n >> m;
    vector<vector<int>> grid(n + 1,vector<int>(m + 1, 0));
    vector<vector<bool>> visited(n + 1,vector<bool>(m + 1, false));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j) cin >> grid[i][j];
    }
    int result = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (!visited[i][j] && grid[i][j])
            {
                count = 1;//最小的岛屿面积其实就是1也就是孤岛
                visited[i][j] = true;
                dfs(grid, visited, i, j);//大家注意我们这里的dfs其实不仅仅找到了岛屿而且还把岛屿面积计算出来了
                result = max(result, count);//不断更新岛屿的面绩
            }
        }
    }
    cout << result << '\n';
    return 0;
}

         当然本题的一些细节我们不可忽略,比如我们搜索的位置不能超出地图的边界,我们还要注意使用一个变量来存储所在的岛屿的面积,大家想明白这一些估计本题目就很简单了。那其实本题目使用广搜也是可以的,我们就需要使用一个队列,我可以给出广搜的代码:

class Solution {
private:
    int count;
    int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
    void bfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {
        queue<int> que;
        que.push(x);
        que.push(y);
        visited[x][y] = true; // 加入队列就意味节点是陆地可到达的点
        count++;
        while(!que.empty()) {
            int xx = que.front();que.pop();
            int yy = que.front();que.pop();
            for (int i = 0 ;i < 4; i++) {
                int nextx = xx + dir[i][0];
                int nexty = yy + dir[i][1];
                if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界
                if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 节点没有被访问过且是陆地
                    visited[nextx][nexty] = true;
                    count++;
                    que.push(nextx);
                    que.push(nexty);
                }
            }
        }
    }

public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<bool>> visited = vector<vector<bool>>(n, vector<bool>(m, false));
        int result = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!visited[i][j] && grid[i][j] == 1) {
                    count = 0;
                    bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
                    result = max(result, count);
                }
            }
        }
        return result;
    }
};

        其实这道题目比较简单,我们的深搜与广搜都可以实现,大家注意理解就可以,我们这道题就分享到这里。

今日总结

        今天我们开始接触了一些岛屿问题,其实我们发现大多都不算难,我们前提是需要掌握好深度优先搜索与广度优先搜索,理解好题意就不难了,比如说今天的这道岛屿的最大面积的题目其实只要理解好前面岛屿的数量的问题就很简单了,我们今天的分享就到这里,我们下一次博客再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2401606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重磅更新! 基于Gemini 2.5 Pro打造的AI智能体PlantUML-X上线!

目录 图表绘制AI智能体PlantUML-X上线通过简单的提示词创建各种UML图&#xff1a;轻松搞定其它类型的技术图表&#xff1a; AI智能体PlantUML-X功能实测画一个在Java中的一个简单的用户登录功能的时序图效果展示&#xff1a;根据详细内容生成系统架构图效果展示&#xff1a;效果…

[5-02-04].第01节:Jmeter环境搭建:

JMeter笔记大纲 Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量 一、JMeter概述&#xff1a; 1.1.JMeter是什么&#xff1a; JMeter是Appache组织使用java开发的一款测试工具 可以用于对服务器、网络或对象模拟巨大的负载…

AI智能推荐实战之RunnableParallel并行链

导读&#xff1a;在现代AI应用开发中&#xff0c;如何高效处理多维度数据分析始终是开发者面临的核心挑战。当您需要同时进行情感分析、关键词提取和实体识别&#xff0c;或者要对比多个AI模型的输出结果时&#xff0c;传统的串行处理方式往往效率低下。 本文将深入解析LangCha…

Gemini开源项目DeepResearch:基于LangGraph的智能研究代理技术原理与实现

引言 在人工智能快速发展的今天&#xff0c;如何构建一个能够进行深度研究、自主学习和迭代优化的AI系统成为了技术前沿的重要课题。Gemini开源的DeepResearch一周收获7.9k Star&#xff0c;Google的开源项目Gemini DeepResearch技术通过结合LangGraph框架和Gemini大语言模型&…

Doris Catalog 联邦分析查询性能优化:从排查到优化的完整指南

在大数据分析中&#xff0c;Doris 的 Catalog 联邦分析功能为整合多源数据提供了有力支持。然而&#xff0c;在实际应用中&#xff0c;可能会遇到各种问题影响其正常运行。本文将详细剖析这些问题并提供解决方案。 一、联邦分析查询慢&#xff1a;内外表通用排查逻辑 当遇到 …

01 Deep learning神经网络的编程基础 二分类--吴恩达

二分类 1. 核心定义 二分类任务是监督学习中最基础的问题类型&#xff0c;其目标是将样本划分为两个互斥类别。设样本特征空间为 X ⊆ R n \mathcal{X} \subseteq \mathbb{R}^n X⊆Rn&#xff0c;输出空间为 Y { 0 , 1 } \mathcal{Y} \{0,1\} Y{0,1}&#xff0c;学习目标为…

视频自动化分割方案:支持按时间与段数拆分

在日常视频处理任务中&#xff0c;如何快速将一个较长的视频文件按照指定规则拆分为多个片段&#xff0c;是许多用户都会遇到的问题。尤其对于需要批量处理视频的开发者、自媒体运营者或内容创作者来说&#xff0c;手动剪辑不仅效率低下&#xff0c;还容易出错。这是一款绿色免…

股指期货合约价值怎么算?

股指期货合约价值就是你买一手股指期货合约&#xff0c;理论上值多少钱。这个价值是根据期货的价格和合约乘数来计算的。就好比你买了一斤苹果&#xff0c;价格是5块钱一斤&#xff0c;那你买一斤就得付5块钱。股指期货也是一样&#xff0c;只不过它的计算稍微复杂一点点。 一…

【QT】使用QT帮助手册找控件样式

选择帮助—》输入stylesheet(小写)—》选择stylesheet—》右侧选择Qt Style Sheets Reference 2.使用CtrlF—》输入要搜索的控件—》点击Customizing QScrollBar 3.显示参考样式表–》即可放入QT-designer的样式表中

计算机网络(5)——数据链路层

1.概述 数据链路层负责一套链路上从一个节点向另一个物理链路直接相连的相邻节点传输数据报。换言之&#xff0c;主要解决相邻节点间的可靠数据传输 节点(nodes)&#xff1a;路由器和主机 链路(links)&#xff1a;连接相邻节点的通信信道 2.数据链路层服务 2.1 组帧 组帧(fra…

VuePress完美整合Toast消息提示

VuePress 整合 Vue-Toastification 插件笔记 记录如何在 VuePress 项目中整合使用 vue-toastification 插件&#xff0c;实现优雅的消息提示。 一、安装依赖 npm install vue-toastification或者使用 yarn&#xff1a; yarn add vue-toastification二、配置 VuePress 客户端增…

adb 连不上真机设备问题汇总

问题一、无法弹出 adb 调试授权弹窗 详细描述&#xff1a; 开发者选项中已打开 usb 调试&#xff0c;仅充电模式下 usb 调试也已打开&#xff0c;电脑通过 usb 连上手机后&#xff0c;一直弹出 adb 调试授权弹窗&#xff0c;尝试取消授权再次连接&#xff0c;还是无法弹出问题…

[yolov11改进系列]基于yolov11引入注意力机制SENetV1或者SENetV2的python源码+训练源码

本文给大家带来的改进机制是SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型Q&#xff0c;而是一个可以和现有的任何一个模型相结合的模块&#xff08;可以看作是一种…

鸿蒙仓颉语言开发实战教程:商城搜索页

大家好&#xff0c;今天要分享的是仓颉语言商城应用的搜索页。 搜索页的内容比较多&#xff0c;都有点密集恐惧症了&#xff0c;不过我们可以从上至下将它拆分开来&#xff0c;逐一击破。 导航栏 搜索页的的最顶部是导航栏&#xff0c;由返回按钮和搜索框两部分组成,比较简单…

图像去雾数据集总汇

自然去雾数据集 部分的数据清洗可以看这里&#xff1a;图像去雾数据集的下载和预处理操作 RESIDE-IN 将ITS作为训练集&#xff0c;SOTSindoor作为测试集。训练集13990对&#xff0c;验证集500对。 目前室内sota常用&#xff0c;最高已经卷到PSNR-42.72 最初应该是dehazefo…

网络攻防技术十四:入侵检测与网络欺骗

文章目录 一、入侵检测概述二、入侵系统的分类三、入侵检测的分析方法1、特征检测&#xff08;滥用检测、误用检测&#xff09;2、异常检测 四、Snort入侵检测系统五、网络欺诈技术1、蜜罐2、蜜网3、网络欺骗防御 六、简答题1. 入侵检测系统对防火墙的安全弥补作用主要体现在哪…

C++笔记-C++11(一)

1.C11的发展历史 C11 是 C 的第⼆个主要版本&#xff0c;并且是从 C98 起的最重要更新。它引⼊了⼤量更改&#xff0c;标准化了既有实践&#xff0c;并改进了对 C 程序员可⽤的抽象。在它最终由 ISO 在 2011 年 8 ⽉ 12 ⽇采纳前&#xff0c;⼈们曾使⽤名称“C0x”&#xff0c;…

JVM 类初始化和类加载 详解

类初始化和类加载 类加载的时机 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的&#xff0c;类型的加载过程必须按照这种顺序按部就班地开始&#xff0c;而解析阶段则不一定&#xff1a;它在某些情况下可以在初始化阶段之后再开始&#xff08;懒解析&#xff09;&am…

B站缓存视频数据m4s转mp4

B站缓存视频数据m4s转mp4 结构分析 结构分析 在没有改变数据存储目录的情况下&#xff0c;b站默认数据保存目录为&#xff1a; Android->data->tv.danmaku.bili->download每个文件夹代表一个集合的视频&#xff0c;比如&#xff0c;我下载的”java从入门到精通“&…

DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_天气预报日历示例(CalendarView01_18)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…