代码随想录算法训练营第51天 | 岛屿数量、岛屿的最大面积

news2024/9/20 5:21:02

目录

岛屿数量

题目描述

输入描述

输出描述

输入示例

输出示例

提示信息

1. 深搜解法

2. 广搜解法

岛屿的最大面积 

题目描述

输入描述

输出描述

输入示例

输出示例

提示信息

1. 深搜解法

2. 广搜解法


岛屿数量

题目描述

给定一个由 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

提示信息

根据测试案例中所展示,岛屿数量共有 3 个,所以输出 3。

数据范围:

1 <= N, M <= 50

如果使用深搜或者广搜,其实还是比较基础的。下面介绍这两种方法。

1. 深搜解法

这里的深搜没有单独写终止条件,因为在循环里面用if判断过了,不满足情况是不会进入递归的,所以保证了其能够终止。

#include<iostream>
#include<vector>
using namespace std;

int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void dfs(vector<vector<int>>& graph, 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 >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
        if(!visited[nextx][nexty] && graph[nextx][nexty] == 1){//没有遍历过且地图上是陆地
            visited[nextx][nexty] = true;
            dfs(graph, visited, nextx, nexty);
        }
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    
    vector<vector<int>> graph(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 >> graph[i][j];
        }
    }
    
    int count = 0;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            if(!visited[i][j] && graph[i][j] == 1){
                visited[i][j] = true;
                count ++;
                dfs(graph, visited, i, j);
            }
        }
    }
    cout << count << endl;
}

 当然也可以单独写终止条件,如下图所示。

#include<iostream>
#include<vector>
using namespace std;

int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void dfs(vector<vector<int>>& graph, vector<vector<bool>>& visited, int x, int y){
    if(visited[x][y] || graph[x][y] == 0) return;//加上了终止条件
    visited[x][y] = 1;
    for(int i = 0; i < 4; i ++){
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        if(nextx < 0 || nextx >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
        dfs(graph, visited, nextx, nexty);
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n, vector<int>(m, 0));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> graph[i][j];
        }
    }
    
    int count = 0;
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            if(!visited[i][j] && graph[i][j] == 1){
                count ++;
                dfs(graph, visited, i, j);
            }
        }
    }
    cout << count << endl;
    return 0;
}

2. 广搜解法

使用广度搜索需要注意标记的时候是在加入队列的时候就要标记,而不是在从队列里面取出来过后才标记,否则会出错。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void bfs(vector<vector<int>>& graph, vector<vector<bool>>& visited, int x, int y){
    queue<int> que;
    que.push(x);
    que.push(y);
    visited[x][y] = 1;
    while(!que.empty()){
        int x = que.front(); que.pop();
        int y = que.front(); que.pop();
        for(int i = 0 ;i < 4; i ++){
            int nextx = x + dir[i][0];
            int nexty = y + dir[i][1];
            if(nextx < 0 || nextx >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
            if(!visited[nextx][nexty] && graph[nextx][nexty] == 1){
                visited[nextx][nexty] = 1;
                que.push(nextx);
                que.push(nexty);//注意这里是在放入队列里面的时候就开始标记已经访问过了,而不是从队列里面取出来的时候才标记
            }
        }
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n, vector<int>(m, 0));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> graph[i][j];
        }
    }
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    
    int count = 0;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            if(!visited[i][j] && graph[i][j] == 1){
                count ++;
                bfs(graph, visited, i, j);
            }
        }
    }
    cout << count << endl;
}

岛屿的最大面积 

题目描述

给定一个由 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

输出示例

4

提示信息

样例输入中,岛屿的最大面积为 4。

数据范围:

1 <= M, N <= 50。

思路:如果上面的题没问题,那这道题其实就非常容易了。

1. 深搜解法

这里是没有单独写终止条件的深搜。这里注意count需要在到达每一块新岛屿的时候从0开始计数。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int  count = 0;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void dfs(vector<vector<int>>& graph, 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 >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
        if(!visited[nextx][nexty] && graph[nextx][nexty] == 1){
            visited[nextx][nexty] = 1;
            count ++;
            dfs(graph, visited, nextx, nexty);
        }
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n, vector<int>(m, 0));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> graph[i][j];
        }
    }
    vector<vector<bool>> visited(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] && graph[i][j] == 1){
                count = 0;//这里需要注意计算每一个岛时都需要置count为0
                visited[i][j] = 1;
                count ++;
                dfs(graph, visited, i, j);
                result = max(result, count);
            }
        }
    }
    cout << result << endl;
}

下面是单独写终止条件的深搜。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int  count = 0;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void dfs(vector<vector<int>>& graph, vector<vector<bool>>& visited, int x, int y){
    if(visited[x][y] || graph[x][y] == 0) return;
    visited[x][y] = 1;
    count ++;
    for(int i = 0; i < 4; i ++){
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        if(nextx < 0 || nextx >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
        dfs(graph, visited, nextx, nexty);
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n, vector<int>(m, 0));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> graph[i][j];
        }
    }
    vector<vector<bool>> visited(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] && graph[i][j] == 1){
                count = 0;//这里需要注意计算每一个岛时都需要置count为0
                dfs(graph, visited, i, j);
                result = max(result, count);
            }
        }
    }
    cout << result << endl;
}

2. 广搜解法

下面是广搜的方法。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int count = 0;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void bfs(vector<vector<int>>& graph, vector<vector<bool>>& visited, int x, int y){
    queue<int> que;
    que.push(x);
    que.push(y);
    count ++;
    visited[x][y] = 1;
    while(!que.empty()){
        int curx = que.front(); que.pop();
        int cury = que.front(); que.pop();
        for(int i = 0 ;i < 4; i ++){
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1];
            if(nextx < 0 || nextx >= graph.size() || nexty < 0 || nexty >= graph[0].size()) continue;
            if(!visited[nextx][nexty] && graph[nextx][nexty] == 1){
                visited[nextx][nexty] = 1;
                que.push(nextx);
                que.push(nexty);//注意这里是在放入队列里面的时候就开始标记已经访问过了,而不是从队列里面取出来的时候才标记
                count ++;
            }
        }
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n, vector<int>(m, 0));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> graph[i][j];
        }
    }
    vector<vector<bool>> visited(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] && graph[i][j] == 1){
                count = 0;
                bfs(graph, visited, i, j);
                result = max(result, count);
            }
        }
    }
    cout << result << endl;
}

感谢你的阅读,希望我的文章能够给你帮助,如果有帮助,麻烦点赞加收藏,或者点点关注,非常感谢。

如果有什么问题欢迎评论区讨论! 

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

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

相关文章

Python和C++气候模型算法模型气候学模拟和统计学数据可视化及指标评估

&#x1f3af;要点 贝叶斯推理气候模型辐射对流及干湿能量平衡模型时间空间气象变化预测模型评估统计指标气象预测数据变换天气和气象变化长短期影响预估降低气候信息尺度评估算法气象行为模拟&#xff1a;碳循环、辐射强迫和温度响应温室气体排放碳循环温室诱导气候变化评估气…

影刀RPA实战:网页爬虫之苦瓜书籍数据

书籍常常被视为心灵的慰藉&#xff0c;因为它们能够在不同的层面上为人们提供支持和安慰。 1. 书籍对我们的重要性 书籍是人类知识的载体&#xff0c;也是智慧的结晶。它们不仅是学习的工具&#xff0c;更是人类心灵的慰藉。在忙碌的生活中&#xff0c;书籍能够提供知识、启发…

VMWare17.5.2中Windows7企业版安装VMWareTools失败及解决办法

一、问题产生环境 宿主机系统&#xff1a;Windows11专业版 x64 虚拟机版本&#xff1a;VMWare17.5.2 虚拟机系统&#xff1a;Windows 7企业版 x64&#xff08;sp1纯净版&#xff09; 二、问题表现现象 在Windows 7企业版系统安装完成后&#xff0c;点击虚拟机编辑&#xff0c;…

安科瑞智能塑壳断路器适用于物联网配电电网中-安科瑞黄安南

智能塑壳断路器是一款多功能、体积小、智能化的塑壳断路器&#xff0c;适用于物联网配电电网中。用于三相四线中性点直接接地的供电、用电系统&#xff0c;能全面采集功率、电能量、功率因数、谐波等用电参数;具有过载、短路、缺相、过压、欠压、剩余电流动作保护等功能&#x…

vscode 环境搭建

1. 插件离线安装 官网链接是&#xff1a;https://marketplace.visualstudio.com/vscode 下载需要的插件&#xff1a; vscode 离线安装 在打开的文件中选择扩展包&#xff0c;点击安装即可 2. 故障解决 参考&#xff1a;https://blog.csdn.net/weixin_63712639/article/det…

Modbus_RTU和Modbus库

目录 一.Modbus_RTU 1. 与Modbus TCP的区别 2. Modbus RTU特点 3. Modbus RTU协议格式 4. 报文详解 5. 代码实现RTU通信 1. 打开模拟的RTU从机 2. linux端使用代码实现和串口连接 2.1. 框架搭建 2.2 代码 二.Modbus库 1.库函数 一.Modbus_RTU 1. 与Modbus T…

el-form中三级动态添加数据

el-form中三级动态添加数据 data数据view按钮触发事件 data数据 submitForm: {id: undefined, //修改IDapp_id: undefined, //IP类型name: , //规则名称sort: undefined, //排序detail: [{keycode: 0,title_one: undefined, //一级标题desc_detail: [{keycode: 0,title_two: u…

vue之我不会 计算属性 vuex 路由 插槽

一、计算属性 例子&#xff1a; 注意&#xff1a;调用计算属性时&#xff0c;不可以带括号&#xff0c;那样调用的就是方法&#xff0c;如&#xff1a;以下调用fullName时不可funnName() <div id"root">姓&#xff1a;<input type"text" v-model&…

iotop 命令:磁盘IO监控和诊断

一、命令简介 ​iotop​命令用于监视磁盘I/O&#xff0c;实时显示每个进程或线程的读写速率等信息。非常适合用于诊断系统中的I/O瓶颈。 ‍ ​​ ‍ 安装 iotop 在大多数Linux发行版中&#xff0c;iotop​可能不是预装的。可以使用包管理器来安装它。 例如&#xff0c;在…

C#|.net core 基础 - 扩展数组添加删除性能最好的方法

今天在编码的时候遇到了一个问题&#xff0c;需要对数组变量添加新元素和删除元素&#xff0c;因为数组是固定大小的&#xff0c;因此对新增和删除并不友好&#xff0c;但有时候又会用到&#xff0c;因此想针对数组封装两个扩展方法&#xff1a;新增元素与删除元素&#xff0c;…

MySQL5.7.42高可用MHA搭建及故障切换演示

系列文章目录 rpmbuild构建mysql5.7RPM安装包 MySQL基于GTID同步模式搭建主从复制 文章目录 系列文章目录前言一、MHA架构介绍1.MHA的功能2.MHA组成3.MHA故障转移过程4.MHA架构优缺点 二、环境准备1.服务器免密2.基于GTID主从复制搭建3.下载mha组件 三、MHA组件安装1.安装依赖…

数据结构——C语言单链表的实现

单链表的实现 一.链表的节点二.如何在在链表中插入数据1.尾插2.改进3.头插4.指定位置pos&#xff0c;在pos前插入数据 三 .删除数据1.头删2.尾删3.指定位置删除数据 一.链表的节点 //链表中的数据类型,方便后续的更改 typedef int SLTDatatype;//链表的节点 typedef struct SL…

学习ROS2第一天—新手笔记(humble版本)

————今早七点达到实验室&#xff0c;吃了早饭收拾了一下现在07&#xff1a;24开始学习———— 1. RO2与ROS1的不同架构&#xff1a; ROS1架构下&#xff0c;所有节点都是Master进行管理 ROS使用基于DDS的Discovery机制&#xff0c;和Master说再见 API的重新设计 编译…

查看ip地址的方法有几种?探索多样方法

在当今数字化时代&#xff0c;IP地址作为网络设备的唯一标识符&#xff0c;在网络连接、数据传输、网络安全等方面扮演着至关重要的角色。无论是普通用户进行网络设置&#xff0c;还是网络管理员进行故障排查&#xff0c;了解如何查看IP地址都是一项基础且必备的技能。本文将深…

2-99 基于matlab多尺度形态学提取眼前节组织

基于matlab多尺度形态学提取眼前节组织&#xff0c;通过应用不同尺度的结构元素进行边缘检测&#xff0c;再通过加权融合的思想来整合检测到的边缘&#xff0c;降低图像噪声的影响&#xff0c;提高边缘检测的精度。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&…

18.DHT11编程案例

温湿度传感器 产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&#xff1a;暖通 空调&#xff1b;汽车&#xff1b;消费品&#xff1b;气象站&#xff1b;湿度调节器&#xff1b;除湿器&#xff1b;家电&#xff1b;医疗…

傅里叶变换的基本性质和有关定理

一、傅里叶变换的基本性质 1.1 线性性质 若 则 其中:a,b是常数 函数线性组合的傅里叶变换等于歌函数傅里叶变换的相应组合。 1.2 对称性 若 则 关于傅里叶变换的对称性还有 虚、实、奇、偶函数的傅里叶变换性质: 1.3 迭次傅里叶变换 对f(x,y)连续两次做二维傅里叶变换…

shell指令及笔试题

一&#xff1a;linux基本指令考察 创建文件&#xff0c;直接在本目录的上级目录下创建一个名为dir1的文件夹&#xff0c;并在dir1文件夹下创建一个名为file1的文件 答&#xff1a;本目录的上级目录下创建一个名为dir1的文件:mkdir ../dir1 在dir1文件夹下创建一个名为file1的…

【CSS in Depth 2 精译_034】5.4 Grid 网格布局的显示网格与隐式网格(下)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

美容美发会员查看源码--———未来之窗行业应用跨平台架构

一、 会员详情查看源码 var obj_未来之窗数据 ;var 未来之窗传送id "这几个举个中文";CyberWin_ClientRender(模板).render(obj_未来之窗数据, function(未来之窗response){CyberWin_Dialog.layer(未来之窗response,{type:"frame",title:"会员详情&q…