图论基础|695. 岛屿的最大面积、1020. 飞地的数量、130. 被围绕的区域

695. 岛屿的最大面积

力扣题目链接(opens new window)

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

  • 输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
  • 输出:6
  • 解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。

思路:广度优先和深度优先皆可,遍历的时候计数,然后取最大数量即可

class Solution {
public:
    //深度优先版本
    int count=0;
    int result =0;
    int dir[4][2]={0,1,1,0,-1,0,0,-1};
    void dfs(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] == 1){
                
                visited[nextx][nexty]=true;
                count++;
                dfs(grid,visited,nextx,nexty);

            }
        }
        
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
       int n=grid.size(); int m=grid[0].size();
        vector<vector<bool>>visited=vector<vector<bool>>(n,vector<bool>(m,false));
        for(int i=0;i<n;i++){
            for(int j=0; j<m;j++){
                if(!visited[i][j]&&grid[i][j]==1){
                    count=1;//遇到陆地先计数
                    visited[i][j]=true;
                    dfs(grid,visited,i,j);
                    result=max(result,count);
                }
            }
        }
        return result;
    }
};
//广度优先版本
class Solution {
public:
 
    int count=0;
    int result =0;
    int dir[4][2]={0,1,1,0,-1,0,0,-1};
    void dfs(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);

                }
            }
        }
        
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
       int n=grid.size(); int m=grid[0].size();
        vector<vector<bool>>visited=vector<vector<bool>>(n,vector<bool>(m,false));
        for(int i=0;i<n;i++){
            for(int j=0; j<m;j++){
                if(!visited[i][j]&&grid[i][j]==1){
                    count=0;
                    visited[i][j]=true;
                    dfs(grid,visited,i,j);
                    result=max(result,count);
                }
            }
        }
        return result;
    }
};

1020. 飞地的数量

力扣链接(opens new window)

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

  • 输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
  • 输出:3
  • 解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。

  • 输入:grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
  • 输出:0
  • 解释:所有 1 都在边界上或可以到达边界

思路:本题要求找到不靠边的陆地面积,那么我们只要从周边找到陆地然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地都变成海洋,然后再去重新遍历地图的时候,统计此时还剩下的陆地就可以了。

遍历周边:分别遍历最左列(grid[i][0]),最右列(grid[i][m-1]),最上行(grid[0][j]),最下行(grid[n-1][j]),同时进行搜索,在搜索过程中将其置0。

class Solution {
public:
    //深度优先搜索
    int dir[4][2]={1,0,0,1,-1,0,0,-1};//四个方向
    int count;
    void dfs(vector<vector<int>>& grid, int x, int y){
        grid[x][y]=0;
        count++;
        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(grid[nextx][nexty]==1){
                // count++;
                // grid[nextx][nexty]=0;
                dfs(grid, nextx, nexty);
            }
        }
        return;
    }
    int numEnclaves(vector<vector<int>>& grid) {
        // int count=0;
        int n=grid.size();//行数
        int m=grid[0].size();//列数
        //遍历周边
        for(int i=0;i<n;i++){
            if(grid[i][0])dfs(grid, i,0);//遍历最左列
            if(grid[i][m-1])dfs(grid,i, m-1);//遍历最右列
        }
        for(int j=0; j<m;j++){
            if(grid[0][j])dfs(grid, 0, j);//遍历最上行
            if(grid[n-1][j])dfs(grid,n-1, j);//遍历最底行
        }
        
        //遍历整个网格,并计数
        count= 0;
        for(int i=0; i<n; i++){
            for(int j=0; j<m;j++){
                if(grid[i][j]){
                    // count++;
                    dfs(grid,i, j);
                }
            }
        }
        return count;
        

    }
};
//广度优先搜索
class Solution {
public:
    int count =0;
    int dir[4][2]={0,1,1,0,0,-1,-1,0};
    void bfs(vector<vector<int>>& grid, int x, int y){
        queue<pair<int,int>>que;
        que.push({x,y});
        count++;
        grid[x][y]=0;
        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(grid[nextx][nexty]){
                    que.push({nextx,nexty});
                    count++;
                    grid[nextx][nexty]=0;
                }

            }
            
        }
        return;
    }
    int numEnclaves(vector<vector<int>>& grid) {
        int n=grid.size();//行数
        int m=grid[0].size();//列数
        //遍历周边并置0
        for(int i=0;i<n;i++){
            if(grid[i][0])bfs(grid,i,0);//遍历最左列
            if(grid[i][m-1])bfs(grid,i,m-1);//遍历最右列
        }
        for(int j=0;j<m;j++){
            if(grid[0][j]) bfs(grid,0,j);//遍历第一行
            if(grid[n-1][j]) bfs(grid,n-1,j);//遍历最后一行
        }
        //重新遍历整个网格并计算
        count=0;
        for(int i=0; i<n;i++) {
            for(int j=0;j<m;j++){
                if(grid[i][j]){
                    bfs(grid,i,j);
                }
            }
        }
        return count;
    }
};

130. 被围绕的区域

题目链接(opens new window)

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

  • 输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
  • 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
  • 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的

思路:和上一题类似,只是需要把’飞地‘改为”X"

先广度优先或深度优先遍历周边,把周边的X换为'A',然后两个for循环遍历整个grid,遇到'A'换成’O',遇到'O'换成‘X'

//广度优先搜索
class Solution {
public:
    int dir[4][2]={0,1,1,0,0,-1,-1,0};
    void dfs(vector<vector<char>>& board, int x, int y){
        board[x][y]='A';
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=board.size()||nexty<0||nexty>=board[0].size())continue;
            if(board[nextx][nexty]=='O'){
                dfs(board,nextx,nexty);
            }
        }
        return;
    }
    void solve(vector<vector<char>>& board) {
        int n=board.size();//行数
        int m=board[0].size();//列数
        //遍历周边,把周边的'O'换成’A‘
        for(int i=0;i<n;i++){
            if(board[i][0]=='O')dfs(board,i,0);//遍历最左列
            if(board[i][m-1]=='O')dfs(board,i,m-1);//遍历最右列
        }

        for(int j=0;j<m;j++){
            if(board[0][j]=='O')dfs(board,0,j);//最上行
            if(board[n-1][j]=='O')dfs(board,n-1,j);//最下行
        }

        //遍历整个网格并替换
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(board[i][j]=='O')board[i][j]='X';
                if(board[i][j]=='A') board[i][j]='O';
                
            }
        }
        

    }
};
class Solution {
public:
    int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
    void bfs(vector<vector<char>>& board, int x, int y) {
        queue<pair<int, int>> que;
        que.push({x, y});
        board[x][y]='A';
        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 >= board.size() || nexty < 0 ||
                    nexty >= board[0].size())
                    continue;
                if (board[nextx][nexty] == 'O') {
                    board[nextx][nexty] = 'A';
                    // cout<<"board[nextx][nexty]:"<<board[nextx][nexty]<<endl;
                    que.push({nextx, nexty});
                    
                }
            }
        }
    }
    void solve(vector<vector<char>>& board) {
        int n = board.size();
        int m = board[0].size();
        // 遍历周边
        for (int i = 0; i < n; i++) {
            if (board[i][0] == 'O')
                bfs(board, i, 0);
            if (board[i][m - 1] == 'O')
                bfs(board, i, m - 1);
        }
        for (int j = 0; j < m; j++) {
            if (board[0][j] == 'O')
                bfs(board, 0, j);
            if (board[n - 1][j] == 'O')
                bfs(board, n - 1, j);
        }

        // 遍历整个网格并替换
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                // cout<<"before: "<<board[i][j]<<endl;
                if (board[i][j] == 'O')
                    board[i][j] = 'X';
                if (board[i][j] == 'A')
                    board[i][j] = 'O';
                
                
            }
        }
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一、Java中SpringCloud组件集成接入【Nacos服务管理】

一、Java中SpringCloud组件集成接入【Nacos服务】 1.Nacos介绍2.搭建Nacos服务2.1Windows部署2.2Linux和Docker部署 3.Nacos可视化操作4.Java集成Nacos5.常见问题5.1将nacos变量读取到程序中作为全局变量 6.参考文章 1.Nacos介绍 Nacos是一个开源的动态服务发现、配置管理和服…

pyvista可视化加强版

增加了一个随机按钮&#xff0c;可以即时切换case可视化 import os import glob import randomimport pyvista as pvdef display_multi_meshes(meshes: list, titlesNone, point_size3, opacity0.9):num len(meshes)for i in range(num):pl.subplot(0, i)if i 2:pl.add_che…

动态规划--子序列问题(一)

一.什么是子序列问题 我们之前已经学习过子数组问题,子数组问题最大的特点就是求一段连续区间的xxxx,子数组问题的经典的状态表示就是以i位置为结束,xxxx,推导状态转移方程的一个经验是根据数组的结构来区分不同的结构 子序列问题本质上是对子数组问题的一个拓展,或者说子序列…

微信怎样群发更高效?

群发是指通过微信平台对特定受众进行大规模信息发布的过程&#xff0c;如节日祝福、活动促销等。随着科技的不断发展&#xff0c;群发的定义已不再仅限于手机信息群发或短信群发。如今&#xff0c;微信内置的群发功能也被广泛应用。 一、微信群发的操作步骤 1. 进入微信&…

C++入门(下)

文章目录 1:引用1.1:引用概念1.2:引用的特性.1.2.1:引用在定义时必须初始化1.2.2:一个变量可以有多个引用1.2.3:引用一旦引用一个实体,再不能引用其他实体. 1.3:应用场景1.3.1:做参数1.3.2:做返回值1.3.2.1:传值返回1.3.2.2:传引用返回(错误示范)1.3.2.3:传引用返回(正确示范) …

Shell脚本学习-if循环

最小化的if语句 无实际用途 if [ ] ;then echo fi 脚本解释 if 判断 [ ] 里面的条件是否成立 后面跟then&#xff0c;代表条件成立 如果在一行则使用分号隔离&#xff08;;&#xff09; 如果不在一行使用则直接在下一行驶入then即可。 如果条件成立则输出echo 后面…

鸿蒙Harmony应用开发—ArkTS-全局UI方法(日期滑动选择器弹窗)

根据指定的日期范围创建日期滑动选择器&#xff0c;展示在弹窗上。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文&#xff0c;不可在UI上下文不明确的地方使用&…

zabbix企业微信的告警媒介配置

简介&#xff1a; Zabbix企业微信告警媒介可用于向特定群组成员发送提醒通知。 前提条件&#xff1a; 完成Zabbix告警平台的搭建后&#xff0c;需将群机器人添加至告警提醒群中。 企业微信群聊——右上角三个点——添加群机器人 保存好产生的webhook地址&#xff08;注意&…

GESP图形化编程一级认证真题 2024年3月

GESP 图形化一级试卷 &#xff08;满分&#xff1a;100 分 考试时间&#xff1a;120 分钟&#xff09; 一、单选题&#xff08;每题 3 分&#xff0c;共 30 分&#xff09; 1、小杨的父母最近刚刚给他买了一块华为手表&#xff0c;他说手表上跑的是鸿蒙&#xff0c;这个 鸿蒙是…

jQuery 基础

文章目录 1. jQuery 概述1.1 JavaScript 库1.2 jQuery 概念1.3 jQuery 优点 2. jQuery 基本使用2.1 下载2.2 使用步骤2.3 jQuery 的入口函数2.4 jQuery 的顶级对象 $2.5 DOM 对象和 jQuery 对象DOM 对象和 jQuery 对象相互转换方法 1. jQuery 概述 1.1 JavaScript 库 1.2 jQue…

【论文阅读】基于多特征融合的智能合约缺陷检测方法

摘要&#xff1a; 1、预处理&#xff1a;颜色标记、词汇提取、字符转换、合约之间的继承关系的提取 2、 使用融合模型进行特征提取&#xff08;BERT、CNN、BiLSTM&#xff09; 3、使用node2vec随机游走算法&#xff0c;将合约之间的继承关系作为输入得到合约关系的特征向量。 4…

python-多参数-放置原则

python-多参数-操作原则&#xff1a; 形参、 位置参数、可变参数居于前&#xff0c;关键字参数居中&#xff0c;可变关键字放到最后 def school(name,location,*args,date_fauned,**kwargs):print(kwargs) school("sss","woshi","mike","…

【openCV】手写算式识别

OpenCV 机器学习库提供了一系列 SVM 函数和类来实现 SVM 模型的训练和预测&#xff0c;方便用户实现自己的 SVM 模型&#xff0c;并应用于分类问题。本文主要介绍使用 openCV 实现手写算式识别的工作原理与实现过程。 目录 1 SVM 模型 1.1 SVM 模型介绍 1.2 SVM 模型原理 2…

使用广播信道的数据链路层

目录 一、局域网的特点 二、媒体共享技术 三、以太网的两个标准 四、以太网 五、CSM/CD协议 1、碰撞检测 2、争用期 3、CSMA/CD重要特性 4、CSMA/CD协议的要点 六、小结 一、局域网的特点 局域网具有如下主要优点&#xff1a; • 具有广播功能&#xff0c; 从一…

Linux系统Docker安装Drupal并配置数据库实现公网远程访问本地站点

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

【07】进阶html5

HTML5 包含两个部分的更新,分别是文档和web api 文档 HTML5 元素表 元素语义化 元素语义化是指每个 HTML 元素都代表着某种含义,在开发中应该根据元素含义选择元素 元素语义化的好处: 利于 SEO(搜索引擎优化)利于无障碍访问利于浏览器的插件分析网页新增元素 多媒体…

Spring6--基础概念

1. 概述 1.1. Spring是什么 Spring 是一套广泛应用于 Java 企业级应用开发领域的轻量级开源框架&#xff0c;由 Rod Johnson 创立&#xff0c;旨在显著降低 Java 企业应用的复杂性&#xff0c;缩短开发周期&#xff0c;并提升开发效率。Spring 不仅适用于服务器端开发&#x…

Lenze伦茨8400变频器E84A L-force Drives 操作使用说明

Lenze伦茨8400变频器E84A L-force Drives 操作使用说明