【算法】bfs解决FloodFill问题

个人主页 : zxctscl
如有转载请先通知

题目

  • FloodFill算法
  • 1. 733. 图像渲染
    • 1.1 分析
    • 1.2 代码
  • 2. 200. 岛屿数量
    • 2.1 分析
    • 2.2 代码
  • 3. 695. 岛屿的最大面积
    • 3.1 分析
    • 3.2 代码
  • 4. 130. 被围绕的区域
    • 4.1 分析
    • 4.2 代码

FloodFill算法

FloodFill就是洪水灌溉,解决的就是下面这样一种模型。
解决性质相同的联通块问题,用的方法就是dfs深度优先搜索遍历:一条道走到黑,直到不能再走,不能再走就倒回去;或者是bfs宽度优先搜索遍历:一层一层剥开

1. 733. 图像渲染

在这里插入图片描述

1.1 分析

用bfs模拟流程
假设有这么一个矩阵,给的位置是(1,1)与(1,1)相连的所有像素相同的点,全部修改为2。
那么就一层一层搜索,就是从(1,1)开始搜索:
第一层从(1,1)开始的上下左右扫描,把(1,2)和(2,1)的值都修改为2;
第二层从(1,2)和(2,1)开始:(1,2)的扫描多加了(0,2);
(2,1)的扫描多了(2,0)和(3,1)
第三层从(0,2)、(2,0)和(3,1)开始:(0,2)多加了(0,3);(2,0)没有;(3,1)多了(3,2)
第四层从(0,3)、(3,2)发现没有了,层序遍历就完成了。
在这里插入图片描述

1.2 代码

class Solution {
    typedef pair<int,int> PII;
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
        int m=image.size(),n=image[0].size();
        int prev=image[sr][sc];//标记一下需要修改的像素值
        if(prev==color)return image;//处理边界情况
       
        queue<PII> 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. 200. 岛屿数量

在这里插入图片描述

2.1 分析

模拟一下过程
以例2模拟:从(0,0)位置开始扩展,不能扩展回去,为了不在原数组上面修改,可以给一个bool数组和原矩阵规模是一样的,然后里面如果存false,就代表这个位置没有遍历过,如果存true表示遍历过。那么从这个位置开始它的上下左右中如果有true,那么就不扫描。

在这里插入图片描述

2.2 代码

class Solution {
    int dx[4] = { 0,0,1,-1 };
    int dy[4] = { 1,-1,0,0 };  
    bool vis[301][301];
    int m,n;
public:
    int numIslands(vector<vector<char>>& grid) {
        m=grid.size(),n=grid[0].size();
        int ret=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(grid[i][j]=='1'&&!vis[i][j])
                {
                    ret++;
                    bfs(grid,i,j);
                }
            }
        }
        return ret;
    }
    void bfs(vector<vector<char>>&grid,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 && grid[x][y]=='1'&&!vis[x][y])
                {
                    q.push({ x,y });
                    vis[x][y]=true;
                }
            }
        }
    }
};

3. 695. 岛屿的最大面积

在这里插入图片描述

3.1 分析

和上面那题类似,就加了一个在dfs里面统计一下面积,然后再返回的这些面积里面找到最大的那个就行。

3.2 代码

class Solution {
     int dx[4] = { 0,0,1,-1 };
    int dy[4] = { 1,-1,0,0 };
    bool vis[51][51];
    int m, n;
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
     
        m = grid.size(), n = grid[0].size();
        int ret = 0;
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (grid[i][j] == 1 && !vis[i][j])
                {
                    
                   ret=max(ret, bfs(grid, i, j));
                }
            }
        }
        return ret;
    }
    int bfs(vector<vector<int>>& grid, int i, int j)
    {
        queue<pair<int, int>>q;
        q.push({ i,j });
        vis[i][j] = true;
        int count = 1;
        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])
                {
                    q.push({ x,y });
                    vis[x][y] = true;
                    count++;
                }
            }
        }
        return count;
    }
    
};

4. 130. 被围绕的区域

在这里插入图片描述

4.1 分析

如果直接开始模拟,那么与边缘相关的联通块就不好做。那么就从与边缘相关的连通块开始做,先遍历四条变,如果边上有0,就先对它们来一个层序遍历,然后把这些位置全部修改为无关的字符。那么接下来就只需要遍历矩阵,把里面的0都修改为x就可以,因为没有被包围的四边已经处理了,剩下的就是一定被包围的。最后在把无关的字符再改回去就可以了。
这个方法叫正难则反,先处理边界上0,改为.,再扫描完矩阵后,还原。

4.2 代码

class Solution {
    int dx[4] = { 0,0,1,-1 };
    int dy[4] = { 1,-1,0,0 };
    int m, n;
public:
    void solve(vector<vector<char>>& board) 
    {
        m=board.size(),n=board[0].size();
        //先处理边界o,把他们修改为a
        for(int j=0;j<n;j++)
        {
            if(board[0][j]=='O')bfs(board,0,j);
             if(board[m-1][j]=='O')bfs(board,m-1,j);
        }

          for(int i=0;i<m;i++)
          {
            if(board[i][0]=='O')bfs(board,i,0);
            if(board[i][n-1]=='O')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]=='a')board[i][j]='O';
          }
         
    }

    void bfs(vector<vector<char>>& board,int i,int j)
    {
        queue<pair<int, int>>q;
        q.push({ i,j });
        board[i][j]='a';
        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] = 'a';
                   
                }
            }
        }
    }

};

有问题请指出,大家一起进步吧!!!

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

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

相关文章

minio-docker单节点部署SDK测试文件上传下载

目录 一&#xff0c;docker部署minio单节点单磁盘 二&#xff0c;SDK测试上传下载 一&#xff0c;docker部署minio单节点单磁盘 1.拉取镜像 # 下载镜像 docker pull minio/minio 2.查看镜像 docker images 3.启动minio(新版本) 创建本机上的挂载目录&#xff0c;这个可以…

蓝桥杯备赛(C/C++组)

README&#xff1a; 本笔记是自己的备考笔记&#xff0c;按照官网提纲进行复习&#xff01;适合有基础&#xff0c;复习用。 一、总考点 试题考查选手解决实际问题的能力&#xff0c;对于结果填空题&#xff0c;选手可以使用手算、软件、编程等方法解决&#xff0c;对于编程大…

Cesium 无人机航线规划

鉴于大疆司空平台和大疆无人机app高度绑定&#xff0c;导致很多东西没办法定制化。 从去年的时候就打算仿大疆开发一套完整的平台&#xff0c;包括无人机app以及仿司空2的管理平台&#xff0c;集航线规划、任务派发、实时图像、无人机管理等功能的平台。 当前阶段主要实现了&…

Kubernetes学习笔记12

k8s核心概念&#xff1a;控制器&#xff1a; 我们删除Pod是可以直接删除的&#xff0c;如果生产环境中的误操作&#xff0c;Pod同样也会被轻易地被删除掉。 所以&#xff0c;在K8s中引入另外一个概念&#xff1a;Controller&#xff08;控制器&#xff09;的概念&#xff0c;…

STM32电机控制固件架构

目录 一、应用程序剖析 二、面向现场的控制实现体系结构 1、参考计算循环 2、电流调节环路 3、安全回路 一、应用程序剖析 上图显示了由ST MC SDK构建的电机控制应用程序。首先&#xff0c;这样的应用程序是由电机控制工作台生成的软件项目&#xff0c;这要归功于STM32Cube…

中国手机频段介绍

中国目前有三大运营商&#xff0c;分别是中国移动、中国联通、中国电信&#xff0c;还有一个潜在的运营商中国广电&#xff0c;各家使用的2/3/4G的制式略有不同 中国移动的GSM包括900M和1800M两个频段。 中国移动的4G的TD-LTE包括B34、B38、B39、B40、B41几个频段&#xff0c;…

纯css实现switch开关

代码比较简单&#xff0c;有需要直接在下边粘贴使用吧~ html: <div class"switch-box"><input id"switch" type"checkbox"><label></label></div> css&#xff1a; .switch-box {position: relative;height: 25px…

SFP光模块和媒体转换器的区别

SFP光模块和媒体转换器都是光电转换设备。它们是否可以互换使用&#xff1f;它们之间有什么区别&#xff1f; SFP光模块与媒体转换器&#xff1a;它们是什么&#xff1f; SFP模块是一种可热插拔的光模块&#xff0c;用于连接网络交换机。它可以将电信号转换为光信号&#xff…

Java - JDK8 下载 安装教程(Mac M芯片)

下载 JDK 安装包 在个人的电脑上&#xff0c;我是比较喜欢使用 zulu 的 JDK&#xff0c;因为它比较早的支持了苹果的 M1 芯片 不论是版本还是功能都非常齐全&#xff0c;各个系统都有对应版本&#xff0c;基于 OpenJDK&#xff0c;免费&#xff0c;下载也方便 官网下载&…

算法——马尔可夫与隐马尔可夫模型

HMM&#xff08;Hidden Markov Model&#xff09;是一种统计模型&#xff0c;用来描述一个隐含未知量的马尔可夫过程&#xff08;马尔可夫过程是一类随机过程&#xff0c;它的原始模型是马尔科夫链&#xff09;&#xff0c;它是结构最简单的动态贝叶斯网&#xff0c;是一种著名…

Qt---控件的基本属性

文章目录 enabled(控件可用状态)geometry(位置和尺寸)简单恶搞程序 windowIcon(顶层 widget 窗口图标)使用 qrc 机制 windowOpacity(窗口的不透明值)cursor(当鼠标悬停空间上的形状)自定义鼠标图标 toolTip(鼠标悬停时的提示)focusPolicy(控件获取焦点的策略)styleSheet(通过CS…

数据集学习

1&#xff0c;CIFAR-10数据集 CIFAR-10数据集由10个类的60000个32x32彩色图像组成&#xff0c;每个类有6000个图像。有50000个训练图像和10000个测试图像。 数据集分为五个训练批次和一个测试批次&#xff0c;每个批次有10000个图像。测试批次包含来自每个类别的恰好1000个随机…

C++的stack和queue类(三):适配所有容器的反向迭代器

目录 前言 list的反向迭代器 list.h文件 ReverseIterator.h文件 test.cpp文件 前言 迭代器按性质分类&#xff1a; 单向&#xff1a;forward_list双向&#xff1a;list随机&#xff1a;vector / deque 迭代器按功能分类&#xff1a; 正向反向const list的反向迭代器…

uni-app web端使用getUserMedia,摄像头拍照

<template><view><video id"video"></video></view> </template> 摄像头显示在video标签上 var opts {audio: false,video: true }navigator.mediaDevices.getUserMedia(opts).then((stream)> {video document.querySelec…

分布式技术---------------消息队列中间件之 Kafka

目录 一、Kafka 概述 1.1为什么需要消息队列&#xff08;MQ&#xff09; 1.2使用消息队列的好处 1.2.1解耦 1.2.2可恢复性 1.2.3缓冲 1.2.4灵活性 & 峰值处理能力 1.2.5异步通信 1.3消息队列的两种模式 1.3.1点对点模式&#xff08;一对一&#xff0c;消费者主动…

架构设计-订单系统之订单系统的架构进化

1、单数据库架构 产品初期&#xff0c;技术团队的核心目标是&#xff1a;“快速实现产品需求&#xff0c;尽早对外提供服务”。 彼时的专车服务都连同一个 SQLServer 数据库&#xff0c;服务层已经按照业务领域做了一定程度的拆分。 这种架构非常简单&#xff0c;团队可以分开…

Pytorch: 利用预训练的残差网络ResNet50进行图像特征提取,并可视化特征图热图

1. 残差网络ResNet的结构 2.图像特征提取和可视化分析 import cv2 import time import os import matplotlib.pyplot as plt import torch from torch import nn import torchvision.models as models import torchvision.transforms as transforms import numpy as npimgname…

汽车咨询|基于SprinBoot的汽车资讯管理系统设计与实现(源码+数据库+文档)

汽车资讯管理系统目录 基于SprinBoot的汽车资讯管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xff…

Promise简单概述

一. Promise是什么&#xff1f; 理解 1.抽象表达&#xff1a; Promise是一门新的技术(ES6规范) Promise是JS中进行异步编程的新解决方案(旧方案是单纯使用回调函数) 异步编程&#xff1a;包括fs文件操作&#xff0c;数据库操作(Mysql)&#xff0c;AJAX&#xff0c;定时器 2.具…

STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978(3)

接前一篇文章&#xff1a;STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978&#xff08;2&#xff09; 本文参考以下文章及视频&#xff1a; STM32CbueIDE Audio播放音频 WM8978 I2S_stm32 cube配置i2s录音和播放-CSDN博客 STM32第二十二课&#xff08;I2S&#xff0c;HAL&am…