BFS算法篇——FloodFill问题的高效解决之道(下)

在这里插入图片描述

文章目录

  • 前言
  • 一. 图像渲染
    • 1.1 题目链接:https://leetcode.cn/problems/flood-fill/description/
    • 1.2 题目分析:
    • 1.3 思路讲解:
    • 1.4 代码实现:
  • 二. 岛屿数量
    • 2.1 题目链接:https://leetcode.cn/problems/number-of-islands/description/
    • 2.2 题目分析:
    • 2.3 思路讲解:
    • 2.4 代码实现:
  • 三. 岛屿的最大面积
    • 3.1 题目链接:https://leetcode.cn/problems/max-area-of-island/description/
    • 3.2 题目分析:
    • 3.3 思路讲解:
    • 3.4 代码实现:
  • 四. 被围绕的区域
    • 4.1 题目链接:https://leetcode.cn/problems/surrounded-regions/description/
    • 4.2 题目分析:
    • 4.3 思路讲解:
    • 4.4 代码实现:
  • 小结

前言

上篇我们简要介绍了用BFS算法解决FloodFill问题,本篇我们将结合具体题目,进一步深化对于该算法的理解运用。

一. 图像渲染

1.1 题目链接:https://leetcode.cn/problems/flood-fill/description/

1.2 题目分析:

  • 有一个m*n的二维数组表示图像,其中的值代表颜色
  • 给出起始坐标和目标颜色,要求与起点相接并且值相同的所有像素点的值,都改为给定color的值
  • 遍历方向为上下左右

1.3 思路讲解:

结合上篇内容很容易联想到使用bfs算法,但是在上下左右四个方向遍历时,可以通过初始化两个数组,大大简化步骤。

在这里插入图片描述
如图,将二维数组映射在平面直角坐标系内,上下左右四个方向的坐标变化如下。

之后我们按照层序遍历的方式,将各个顶点依次入队列,并按照上下左右的方向遍历判断即可。

1.4 代码实现:

class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
        int prev=image[sr][sc];
        int dx[]={0,0,-1,1};
        int dy[]={1,-1,0,0};
        int m=image.size();//行
        int n=image[0].size();//列
        if(prev==color)
        {
            return image;
        }//处理特殊情况
        queue<pair<int,int>> q;
        q.push({sr,sc});
        while(q.size())
        {
            auto [a,b]=q.front();
            q.pop();
            image[a][b]=color;
            //下一层入队列
            //处理边界情况
            for(int i=0;i<4;i++)
            {
                int x=a+dx[i],y=b+dy[i];
                if(x>=0&&x<m&&y>=0&&y<n&&image[x][y]==prev)
                {
                    q.push({x,y});
                }
            }
            
        }
        return image;
        
    }
};

二. 岛屿数量

2.1 题目链接:https://leetcode.cn/problems/number-of-islands/description/

2.2 题目分析:

  • 给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

  • 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。(不考虑斜侧方向,只考虑水平和竖直)

  • 此外,你可以假设该网格的四条边均被水包围。

2.3 思路讲解:

岛屿与上题的上色问题类似,都要求一个点内附近相接的同属性点。
通俗来讲,即一大块相接且被0围住的1,即代表一块岛屿。

因此,我们可以遍历数组内的每一个点,如果为1,则说明此处有一个岛屿,使用bfs算法将其周围的1全部转化为0

注意:本题并未提到原数组是否可以更改,因此我们为了以防万一,可以通过标记数组的方式进行1的转换。

2.4 代码实现:

class Solution {
public:
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};
    bool vis[301][301]={0};
    int m,n;
    int ret=0;//岛屿数量
    void bfs(vector<vector<char>>& gird,int i,int j)
    {
        queue<pair<int,int>> q;
        q.push({i,j});
        vis[i][j]=true;
        while(q.size())
        {
            auto [a,b]=q.front();
            q.pop();
                
            for(int k=0;k<4;k++)
            {
            
                int x=a+dx[k],y=b+dy[k];
                if(x>=0&&x<m&&y>=0&&y<n&&vis[x][y]==0&&gird[x][y]=='1')
                {
                    q.push({x,y});
                    vis[x][y]=true;
                }
            }
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        m=grid.size(),n=grid[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(grid[i][j]=='1'&&vis[i][j]==0)
                {
                    ret++;
                    bfs(grid,i,j);
                }
            }
        }
        return ret;
        
        
    }
};

三. 岛屿的最大面积

3.1 题目链接:https://leetcode.cn/problems/max-area-of-island/description/

3.2 题目分析:

  • 岛屿的规则与上相同
  • 本题要求返回岛屿的最大面积,而非岛屿的数量

3.3 思路讲解:

大体思路与上题相同,只需要记录下遍历过程中最大的岛屿面积,并在最终返回即可。

3.4 代码实现:

class Solution {
public:
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};
    bool vis[51][51]={false};//标记数组
    int m,n;
    int ret=0;//最大面积
    int bfs(vector<vector<int>>& grid,int i,int j)
    {
        int count=1;//记录该岛屿面积
        queue<pair<int,int>> q;
        q.push({i,j});
        vis[i][j]=true;
        while(q.size())
        {
            auto [a,b]=q.front();
            q.pop();
            for(int k=0;k<4;k++)
            {
                int x=a+dx[k],y=b+dy[k];
                if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]==1&&vis[x][y]==0)
                {
                    q.push({x,y});
                    count++;
                    vis[x][y]=true;
                }
            }
        }
        return count;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        m=grid.size(),n=grid[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(grid[i][j]==1&&vis[i][j]==0)
                {
                    int temp=bfs(grid,i,j);
                    ret=max(ret,temp);
                }

            }
        }
        return ret;
        
    }
};

四. 被围绕的区域

4.1 题目链接:https://leetcode.cn/problems/surrounded-regions/description/

4.2 题目分析:

  • 给定一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ 组成,捕获所有被围绕的区域
  • 围绕区域指被X包围的O
  • 捕获指将O替换为X

4.3 思路讲解:

  • 首先需要明确,最外层的O由于没有被X包围,因此是永远不会被替换的
  • 因此被替换的只有边界内的O

所以我们只需要利用BFS算法遍历并替换即可。

注意:由于BFS算法在上下左右遍历时,可能存在边界上有O的情况,处理起来较为复杂。我们可以采取正难则反的思路。
在遍历之前,将边界上所有的O转化为*

4.4 代码实现:

class Solution {
public:
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};
    int m,n;
    void bfs(vector<vector<char>>& board,int i,int j)
    {
        queue<pair<int,int>> q;
        q.push({i,j});
        while(q.size())
        {
            auto [a,b]=q.front();
            q.pop();
            for(int k=0;k<4;k++)
            {
                int x=a+dx[k],y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && board[x][y]=='O')
                {
                    q.push({x,y});
                    board[x][y]='*';
                }
            }
        }
    }
    void solve(vector<vector<char>>& board) {
        m=board.size(),n=board[0].size();
        //遍历最上和最下两行
        for(int j=0;j<n;j++)
        {
            if(board[0][j]=='O')
            {
                board[0][j]='*';
                bfs(board,0,j);
            }
            if(board[m-1][j]=='O')
            {
                board[m-1][j]='*';
                bfs(board,m-1,j);
            }

        }
        //遍历最左和最右两列
        for(int i=0;i<m;i++)
        {
            if(board[i][0]=='O')
            {
                board[i][0]='*';
                bfs(board,i,0);
            }
            if(board[i][n-1]=='O')
            {
                board[i][n-1]='*';
                bfs(board,i,n-1);
            }
        }
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(board[i][j]=='O')
                {
                    board[i][j]='X';
                }
                else if(board[i][j]=='*')
                {
                    board[i][j]='O';
                }
            }
        }//还原操作


        
    }
};

小结

本篇关于BFS算法的介绍就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!
在这里插入图片描述

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

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

相关文章

DEEPSEEK与GPT等AI技术在机床数据采集与数字化转型中的应用与影响

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;深度学习、自然语言处理等先进技术开始广泛应用于各行各业。在制造业尤其是机床行业&#xff0c;AI技术的融合带来了巨大的变革&#xff0c;尤其在机床数据采集与机床数字化方面的应用。本文将探讨DEEPSEEK、…

android手机安装deepseek-r1:1.5b

序 本文主要展示一下如何在android手机上安装deepseek-r1:1.5b 步骤 安装termux 到https://termux.dev/cn/index.html去下载 然后执行termux-setup-storage以获取手机存储权限 安装构建依赖 pkg install git cmake golang下载ollama git clone --depth 1 https://gitee.…

单张照片可生成写实3D头部模型!Adobe提出FaceLift,从单一的人脸图像中重建出360度的头部模型。

FaceLift是Adobe和加州大学默塞德分校推出的单图像到3D头部模型的转换技术,能从单一的人脸图像中重建出360度的头部模型。FaceLift基于两阶段的流程实现:基于扩散的多视图生成模型从单张人脸图像生成一致的侧面和背面视图;生成的视图被输入到GS-LRM重建器中,产出详细的3D高斯表…

如何使用 DataX 连接 Easysearch

DataX DataX 是阿里开源的一款离线数据同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle 等)、HDFS、Hive、ODPS、HBase、FTP 等各种异构数据源之间稳定高效的数据同步功能。 本篇主要介绍 DataX 如何将数据写入到 Easysearch&#xff0c;对于各种数据源的连接…

Gemini 2.0模型更新:谷歌最新AI大模型全面开启智能时代

引言 2025年2月5日&#xff0c;谷歌人工智能实验室&#xff08;Google DeepMind&#xff09;发布了最新的Gemini 2.0模型系列更新&#xff0c;包括2.0 Flash、Flash-Lite和Pro实验版本。这些AI大模型的发布标志着人工智能技术在性能、效率和多模态能力上的进一步突破&#xff…

Visual Studio 2022 中使用 Google Test

要在 Visual Studio 2022 中使用 Google Test (gtest)&#xff0c;可以按照以下步骤进行&#xff1a; 安装 Google Test&#xff1a;确保你已经安装了 Google Test。如果没有安装&#xff0c;可以通过 Visual Studio Installer 安装。在安装程序中&#xff0c;找到并选择 Googl…

基于SpringBoot的校园社交平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【R语言】数据重塑

一、定义 R语言中&#xff0c;数据重塑&#xff08;Data Reshaping&#xff09;是指改变数据框&#xff08;data frame&#xff09;或类似结构&#xff08;如矩阵、列表等&#xff09;的形状&#xff0c;以适应不同的分析或可视化需求。这通常涉及行和列的重新排列、数据的汇总…

【银河麒麟高级服务器操作系统】系统日志Call trace现象分析及处理全流程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…

代码随想录_二叉树

二叉树 二叉树的递归遍历 144.二叉树的前序遍历145.二叉树的后序遍历94.二叉树的中序遍历 // 前序遍历递归LC144_二叉树的前序遍历 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result new ArrayList<Integer&g…

科普书《从一到无穷大》的科普知识推翻百年集论

科普书《从一到无穷大》的科普知识推翻百年集论 黄小宁 “我们给两组无穷大数列中的各个数一一配对&#xff0c;如果最后这两组都一个不剩&#xff0c;这两组无穷大就是相等的&#xff1b;如果有一组还有些数没有配出去&#xff0c;这一组就比另一组大些&#xff0c;或者说强些…

算法【Java】—— 动态规划之回文串问题

回文子串 https://leetcode.cn/problems/palindromic-substrings 我们可以使用二维的 dp 表记录所有的子串情况&#xff0c;dp[i][j] 表示 以 i 起始&#xff0c;j 结尾的子串是否是回文串 状态转移方程推导&#xff1a;回文串要求开头和结尾的两个元素必须是相同的&#xff…

【Linux】从零开始:编写你的第一个Linux进度条小程序

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言专栏&#xff1a;C语言 &am…

01_Machine Vision_LSI及傅立叶变换

outline 图像分解和线性时不变系统二维傅立叶变换图像采样 图像分解和线性时不变系统 图像数学表达 图像由基本的像素点组成&#xff0c;如果将每一个像素点看作一个脉冲&#xff0c;则每个像素点的值可以看作是脉冲的幅值&#xff0c;这样图像就可以看作是由一系列脉冲组成…

Win11下搭建Kafka环境

目录 一、环境准备 二、安装JDK 1、下载JDK 2、配置环境变量 3、验证 三、安装zookeeper 1、下载Zookeeper安装包 2、配置环境变量 3、修改配置文件zoo.cfg 4、启动Zookeeper服务 4.1 启动Zookeeper客户端验证 4.2 启动客户端 四、安装Kafka 1、下载Kafka安装包…

自动化xpath定位元素(附几款浏览器xpath插件)

在 Web 自动化测试、数据采集、前端调试中&#xff0c;XPath 仍然是不可或缺的技能。虽然 CSS 选择器越来越强大&#xff0c;但面对复杂 DOM 结构时&#xff0c;XPath 仍然更具灵活性。因此&#xff0c;掌握 XPath&#xff0c;不仅能提高自动化测试的稳定性&#xff0c;还能在爬…

尝试一下,交互式的三维计算python库,py3d

py3d是一个我开发的三维计算python库&#xff0c;目前不定期在PYPI上发版&#xff0c;可以通过pip直接安装 pip install py3d 开发这个库主要可视化是想把自己在工作中常用的三维方法汇总积累下来&#xff0c;不必每次重新造轮子。其实现成的python库也有很多&#xff0c;例如…

手机向电脑传输文件方法有哪些?

手机和电脑已经成为我们日常生活和工作中不可或缺的工具&#xff0c;而它们之间的文件传输需求也日益增加。为了帮助大家更高效地完成这一任务&#xff0c;本文将介绍三种常用的手机向电脑传输文件方法&#xff0c;方便您根据不同场景选择合适的方式。 方法1.数据线 当您有数…

【ESP32】ESP-IDF开发 | WiFi开发 | HTTP服务器

1. 简介 1.1 HTTP HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;全称超文本传输协议&#xff0c;用于从网络服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效&#xff0c;使网络传输减少。它不仅保证计算机正确快速地传输超文本文档…

生成式聊天机器人 -- 基于Pytorch + Global Attention + 双向 GRU 实现的SeqToSeq模型 -- 下

生成式聊天机器人 -- 基于Pytorch Global Attention 双向 GRU 实现的SeqToSeq模型 -- 下 训练Masked 损失单次训练过程迭代训练过程 测试贪心解码(Greedy decoding)算法实现对话函数 训练和测试模型完整代码 生成式聊天机器人 – 基于Pytorch Global Attention 双向 GRU 实…