FloodFill

"绝境之中才窥见,Winner,Winner" 


FloodFill算法简介:

        floodfill又翻译成漫水填充。我们可以将下面的矩阵理解为一片具有一定高度的坡地,此时突发洪水,洪水会将高度<0的地方填满。        

        话句话来说,FloodFill算法是为了找出那些具有相同性质的区域。那我们现在就来看看一些经典的使用floodfill算法的题目。


图像渲染

(1) 题目解析        

                这类题目的代码部分,都是将模拟的过程转化成代码。

(2) 算法代码

dfs:

class Solution {
public:int m,n;int prev;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {m = image.size(),n = image[0].size();if(image[sr][sc] == color) return image;prev = image[sr][sc];dfs(image,sr,sc,color);return image;}void dfs(vector<vector<int>>& image, int i,int j,int newcolor){// 从这一点出发,每一个方向去 递归相邻节点image[i][j] = newcolor;for(int k=0;k<4;++k){int x=i+dx[k],y = j+dy[k];// 满足 要渲染更改的值 if(x>=0 && x<m && y>=0 && y<n && image[x][y] == prev){dfs(image,x,y,newcolor);}}}
};

 bfs:       

class Solution {
public:typedef pair<int,int> PII;int m,n;int prev;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {m = image.size(),n = image[0].size();if(image[sr][sc] == color) return image;// 当前位置会被修改为newcolor 这里是保存需要被渲染的值prev = image[sr][sc];bfs(image,sr,sc,color);return image;}void bfs(vector<vector<int>>& image, int i,int j,int newcolor){queue<PII> que;image[i][j] = newcolor;que.push({i,j});while(que.size()){// 取出已经被渲染的位置,并将它的相邻位置,满足条件的 插入进队列auto [a,b] = que.front();que.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 && image[x][y] == prev){image[x][y] = newcolor;que.push({x,y});}}}}
};

岛屿数量

(1) 题目解析        

注: 进行bfs或dfs时需要注意,防止统计已经遍历过的位置。我们有两种解决方法,其一就是对原数组内部的值进行修改,区别于目标条件,其二就是创建一个新的布尔数组,标记每一个遍历过的点。

(2) 算法代码

dfs:        

class Solution {
public:int m,n;bool vis[301][301];int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int numIslands(vector<vector<char>>& grid) {m = grid.size(),n = grid[0].size();int count = 0;for(int i=0;i<m;++i)for(int j=0;j<n;++j){// 遍历到岛屿进行一次dfs 并且这个位置没有被访问过if(grid[i][j] == '1' && !vis[i][j]) {count++;vis[i][j] = true; // 标记dfs(grid,i,j);}}return count;}void dfs(vector<vector<char>>& grid,int i,int j){// 这里的dfs 只需将与(i,j) 相连的岛屿统计即可for(int k=0;k<4;++k){int x=i+dx[k],y=j+dy[k];if(x>=0 && x<m && y>=0 && y<n && grid[x][y] == '1' && !vis[x][y]){vis[x][y] = true;dfs(grid,x,y);}}}
};

bfs:

    class Solution {public:int m,n;bool vis[301][301];int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int numIslands(vector<vector<char>>& grid) {m = grid.size(),n = grid[0].size();int count = 0;for(int i=0;i<m;++i)for(int j=0;j<n;++j){// 遍历到岛屿进行一次dfs 并且这个位置没有被访问过if(grid[i][j] == '1' && !vis[i][j]) {count++;vis[i][j] = true; // 标记bfs(grid,i,j);}}return count;}void bfs(vector<vector<char>>& grid,int i,int j){// 这里的bfs 只需将与(i,j) 相连的岛屿统计即可// bfs通常需要借助队列来实现queue<pair<int,int>> que;que.push({i,j});while(que.size()){auto [a,b] = que.front();que.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]){vis[x][y] = true;que.push({x,y});}}}}};

岛屿的最大面积

(1) 题目解析        

        这道题和上个题目十分类似,只不过这道题目的结果是求这些岛屿的最大面积,所以,我们需要对相连岛屿数量进行统计,并最终返回一个最大值。

(2) 算法代码

dfs:

class Solution {
public:int m,n;bool vis[301][301];int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int ret,count;int maxAreaOfIsland(vector<vector<int>>& grid) {m = grid.size(),n = grid[0].size(),ret = 0;for(int i=0;i<m;++i)for(int j=0;j<n;++j){// 遍历到岛屿进行一次dfs 并且这个位置没有被访问过if(grid[i][j] == 1 && !vis[i][j]) {count = 0;dfs(grid,i,j);ret = max(ret,count);}}return ret;}void dfs(vector<vector<int>>& grid,int i,int j){vis[i][j] = true;count++;for(int k=0;k<4;++k){int x=i+dx[k],y=j+dy[k];if(x>=0 && x<m && y>=0 && y<n && grid[x][y] == 1 && !vis[x][y]){ dfs(grid,x,y);}}}
};

bfs:

class Solution {
public:int m,n;bool vis[301][301];int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int ret,count;int maxAreaOfIsland(vector<vector<int>>& grid) {m = grid.size(),n = grid[0].size(),ret = 0;for(int i=0;i<m;++i)for(int j=0;j<n;++j){// 遍历到岛屿进行一次dfs 并且这个位置没有被访问过if(grid[i][j] == 1 && !vis[i][j]) {count = 0;vis[i][j] = true; // 标记bfs(grid,i,j);ret = max(ret,count);}}return ret;}void bfs(vector<vector<int>>& grid,int i,int j){// 这里的bfs 只需将与(i,j) 相连的岛屿统计即可// bfs通常需要借助队列来实现queue<pair<int,int>> que;que.push({i,j});count++;while(que.size()){auto [a,b] = que.front();que.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]){count++;vis[x][y] = true;que.push({x,y});}}}}
};


被围绕的区域

(1) 题目解析        

        但其实,我们发现这两个dfs本质是做同样的事情,但却因为判断边界,我们需要写两份不同的dfs,这是蛮麻烦的事情。我们换个思路,直接用一个dfs将边界的'O',进行过滤,并填上不相关的字符,再将整个数组遍历,遇到‘O’改为‘X’,遇到这个不相关的字符,改为'O'。

(2) 算法代码

dfs:

class Solution {
public:int m,n;bool vis[201][201];int dx[4] = {0,0,-1,1};int dy[4] = {1,-1,0,0};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') dfs(board,0,j);if(board[m-1][j] == 'O') dfs(board,m-1,j);}// 第一列 最后一列for(int i=0;i<m;++i){if(board[i][0] == 'O') dfs(board,i,0);if(board[i][n-1] == 'O') dfs(board,i,n-1);}for(int i=0;i<m;++i)for(int j=0;j<n;++j){if(board[i][j] == '.') board[i][j] = 'O';else if(board[i][j] == 'O') board[i][j] = 'X';}}void dfs(vector<vector<char>>& board,int i,int j){board[i][j] = '.';for(int k=0;k<4;++k){int x=i+dx[k],y=j+dy[k];if(x>=0 && x<m && y>=0 && y<n && board[x][y] == 'O'){dfs(board,x,y);}}}
};

bfs:        

class Solution {
public:int m,n;bool vis[201][201];int dx[4] = {0,0,-1,1};int dy[4] = {1,-1,0,0};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') 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] == '.') board[i][j] = 'O';else if(board[i][j] == 'O') board[i][j] = 'X';}}void bfs(vector<vector<char>>& board,int i,int j){board[i][j] = '.';queue<pair<int,int>> que;que.push({i,j});while(que.size()){auto [a,b] = que.front();que.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'){board[x][y] = '.';que.push({x,y});}}}}
};

扫雷

(1) 题目解析        

        经典的扫雷游戏,至于玩法也就不过多解释。该题目考察的地方就在于,点击一个点之后,从这个 点开始进行对相邻领域的展开,我们可以采用dfs或bfs完成。

        当挖出的位置是一个雷,将这个位置标记成‘X’,游戏结束。当挖出的一个地方是空位置,你需要首先去相邻区域查找是否有雷,如果没有发现雷,则标记为'B',否则就需要将搜查到的雷的个数,标记在该位置处。

(2) 算法代码

dfs:

class Solution {
public:int m,n;bool vis[51][51];// 扫雷位置有八个位置需要被展开int dx[8] = {0,0,-1,1,-1,1,-1,1};int dy[8] = {1,-1,0,0,1,-1,-1,1};vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {m = board.size(),n = board[0].size();int i = click[0],j = click[1];if(board[i][j] == 'M')board[i][j] = 'X';elsedfs(board,i,j);return board;}void dfs(vector<vector<char>>& board,int i,int j){int count = 0;// 统计雷的数量for(int k=0;k<8;++k){int x=i+dx[k],y=j+dy[k];if(x>=0 && x<m && y>=0 && y<n && board[x][y] == 'M') count++;}if(count){board[i][j] = count + '0';}else{board[i][j] = 'B';for(int k=0;k<8;++k){int x=i+dx[k],y=j+dy[k];if(x>=0 && x<m && y>=0 && y<n && board[x][y] == 'E') dfs(board,x,y);}}}
};

bfs:        

class Solution {
public:int m,n;bool vis[51][51];// 扫雷位置有八个位置需要被展开int dx[8] = {0,0,-1,1,-1,1,-1,1};int dy[8] = {1,-1,0,0,1,-1,-1,1};vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {m = board.size(),n = board[0].size();int i = click[0],j = click[1];if(board[i][j] == 'M')board[i][j] = 'X';elsebfs(board,i,j);return board;}void bfs(vector<vector<char>>& board,int i,int j){queue<pair<int,int>> que;que.push({i,j});vis[i][j] = true;while(que.size()){auto [a,b] = que.front();que.pop();int count = 0;// 统计雷的数量for(int k=0;k<8;++k){int x=a+dx[k],y=b+dy[k];if(x>=0 && x<m && y>=0 && y<n && board[x][y] == 'M') count++;}if(count){board[a][b] = count + '0';}else{board[a][b] = 'B';for(int k=0;k<8;++k){int x=a+dx[k],y=b+dy[k];if(x>=0 && x<m && y>=0 && y<n && board[x][y] == 'E'){// 这里改为'B' 避免被其他点统计到 队列中去// 也可以使用 vis[x][y] = ture; 进行标记 不被统计 !!!board[x][y] = 'B'; que.push({x,y});}}}}}
};


本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

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

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

相关文章

IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8?(已解决)

文章目录 前言分析解决方案一&#xff1a;替换创建项目的源方案二&#xff1a;升级JDK版本 参考文献 前言 起因 想创建一个springboot的项目&#xff0c;本地安装的是1.8&#xff0c;但是在使用Spring Initializr创建项目时&#xff0c;发现版本只有17和21。 在JDK为1.8的情况下…

代码随想录算法训练营第四十六天【动态规划part08】 | 139.单词拆分、背包总结

139.单词拆分 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 单词是物品&#xff0c;字符串s是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。 动规五部曲 确定dp数…

弹窗concrt140.dll丢失的解决方法,深度解析concrt140.dll丢失的原因

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示或者系统崩溃的情况。其中&#xff0c;concrt140.dll是一个常见的错误提示&#xff0c;这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;本文将介绍5种详细的解决方法&#xff0c;帮助您恢…

蓝桥杯官网算法赛(蓝桥小课堂)

问题描述 蓝桥小课堂开课啦&#xff01; 海伦公式&#xff08;Herons formula&#xff09;&#xff0c;也称为海伦-秦九韶公式&#xff0c;是用于计算三角形面积的一种公式&#xff0c;它可以通过三条边的长度来确定三角形的面积&#xff0c;而无需知道三角形的高度。 海伦公…

Python 进阶(十):数学计算(math 模块)

《Python入门核心技术》专栏总目录・点这里 文章目录 1. 导入math模块2. 常用数学函数3. 常量4. 其他函数和用法5. 总结 大家好&#xff0c;我是水滴~~ Python的math模块提供了许多数学运算函数&#xff0c;为开发者在数值计算和数据处理方面提供了强大的工具。本教程将详细介…

【100个Cocos实例】看完这个,我再也不要当赌狗了...

引言 探索游戏开发中抽奖转盘的奥秘。 抽奖转盘是一种常见的互动元素&#xff0c;通常用于游戏、营销活动等场景。 本文将介绍一下抽奖转盘的原理和实现。 本文源工程可在文末阅读原文获取&#xff0c;小伙伴们自行前往。 1.抽奖转盘的组成 抽奖转盘的实现涉及多个组成部分…

基于springboot校园车辆管理系统

背景 伴随着社会经济的快速发展&#xff0c;机动车保有量不断增加。不断提高的大众生活水平以及人们不断增长的自主出行需求&#xff0c;人们对汽车的 依赖性在不断增强。汽车已经发展成为公众日常出行的一种重要的交通工具。在如此形势下&#xff0c;高校校园内的机动车数量也…

【KubeSphere】基于AWS在 Linux 上以 All-in-One 模式安装 KubeSphere

文章目录 一、实验配置说明二、实验准备工作1.确认系统版本2. 修改网络DNS3. 关闭SELINUX4. 关闭防火墙 三、实验依赖项安装四、下载 KubeKey五、一键化安装部署六、验证安装结果七、登录KubeSphere管理控制台八、参考链接 一、实验配置说明 本实验基于AWS启动一台新实例&…

I/O多路转接之epoll

承接上文 I/O多路转接之poll-CSDN博客 简介 epoll的相关系统调用 epoll底层原理 编写epoll的server 重新回归一下epoll原理&#xff0c;LT&#xff0c;ET epoll改成ET工作模式 -- 初识(有bug) epoll初识 按照man手册的说法: 是为处理大批量句柄而作了改进的poll. 它是在2.5.4…

CANdelaStudio 使用教程4 编辑State

文章目录 简述1、State Groups2、Dependencies3、 Defaults State1、 会话状态2、 新增会话状态3、 编辑 服务对 State 的依赖关系 State Diagram 简述 1、State Groups 2、Dependencies 在这里&#xff0c;可以编辑现有服务在不同会话状态或安全访问状态的支持情况和状态转换…

粒子群算法Particle Swarm Optimization (PSO)的定义,应用优点和缺点的总结!!

文章目录 前言一、粒子群算法的定义二、粒子群算法的应用三、粒子群算法的优点四、粒子群算法的缺点&#xff1a;粒子群算法的总结 前言 粒子群算法是一种基于群体协作的随机搜索算法&#xff0c;通过模拟鸟群觅食行为而发展起来。该算法最初是由Eberhart博士和Kennedy博士于1…

概念解析 | 玻尔兹曼机

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:玻尔兹曼机。 概念解析 | 玻尔兹曼机 引言 随着人工智能技术的飞速发展,玻尔兹曼机作为一种重要的生成模型,受到了广泛的关注。 背景介绍 玻尔兹曼机(Boltzmann Machine)是一…

uniapp+vue基于Android的校园二手跳蚤市场的设计与实现 微信小程序

实现功能&#xff1a; 用户管理&#xff1a;登陆、注册、注销、修改密码、上传头像、修改资料 发布与检索&#xff1a;发布商品、模糊搜索、人气排序、价格排序、时间排序、推送商品&#xff08;协同过滤算法实现个性化推荐&#xff09;&#xff0c;最新发布、分类检索 核心交易…

1、分布式锁实现原理与最佳实践(一)

在单体的应用开发场景中涉及并发同步时&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或同一个JVM内Lock机制来解决多线程间的同步问题。而在分布式集群工作的开发场景中&#xff0c;就需要一种更加高级的锁机制来处理跨机器的进程之间的数据同步问题&…

安卓系统修图软件(二)

晚上好&#xff0c;自上一次博主分享修图软件之后&#xff0c;今天博主将带来第二期安卓修图软件的推送&#xff0c;个个都是宝藏&#xff0c;建议大家赶紧体验哦。 1.canva可画 如果说有一款手机APP可以与PS媲美&#xff0c;那么一定非canvas莫属。这款强大的修图软件支持海报…

java springboot测试类虚拟MVC环境 匹配请求头指定key与预期值是否相同

上文 java springboot测试类虚拟MVC环境 匹配返回值与预期内容是否相同 (JSON数据格式) 版 中 我们展示 json匹配内容的方式 那么 本文我们来看看Content-Type属性的匹配方式 首先 我们从返回体可以看出 Content-Type 在请求头信息 Headers 中 我们直接将测试类代码更改如下 …

企业文档文件管理软件推荐:提升管理效率与数据安全性

Zoho WorkDrive企业网盘是一种高效的文件管理工具&#xff0c;它不仅可以为组织搭建统一、高效、安全、智能的内容管理体系&#xff0c;还能够提供大规模支撑、海量数据处理、非结构化数据治理、智能挖掘与洞察等服务能力。通过这些服务&#xff0c;企业可以更好地管理和利用其…

leetcode 41. 缺失的第一个正数

目录 暴力排序 桶排序 桶排序Set 桶排序分治思想 官方题解 桶排序数组内标记 桶排序额外数组标记&#xff08;更好理解&#xff09; 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额…

Rust在Web开发中的应用

欢迎关注我的公众号lincyang新自媒体&#xff0c;回复关键字【程序员经典书单】&#xff0c;领取程序员的100本经典书单 大家好&#xff01;我是lincyang。 今天我们将一起深入探索Rust在Web开发领域的应用。尽管Rust最初设计用于系统编程&#xff0c;但其性能、安全性和现代并…

只狼 资源分享

版本介绍 v1.06版|容量15GB|官方简体中文|支持键盘.鼠标.手柄|赠官方原声4首BGM|赠多项修改器|赠一周目全义手忍具强化通关存档|2020年01月15号更新 只狼中文设置&#xff1a; https://jingyan.baidu.com/article/cb5d6105bc8556005d2fe048.html 只狼键盘对应按键&#xff1…