我爱学算法之——floodfill算法(上)

我爱学算法之——floodfill算法(上)

前言

Flood Fill(也称为种子填充算法)是一种用于确定连接到多维数组中给定节点的区域的算法

核心思想

  • 从起点开始:从一个初始像素(种子点)开始
  • 扩散填充:向四周(通常为4方向或8方向)扩展
  • 条件匹配:只填充与种子点颜色相同且相邻的像素
  • 避免重复:标记已访问的位置,防止重复处理

一、图像渲染

题目解析

在这里插入图片描述

给定一个 m*n 的二维数组,从起始位置 [sr,sc] 开始,将从起始位置的 上下左右 四个方向上 相邻且与起始位置初始颜色相同的像素点进行染色,直到没有其他原始颜色的相邻像素。

算法思路

这道题整体还是非常简单的,从起始位置开始,进行一次深度优先遍历 DFS 即可。

注意:当起始位置[sr, sc]的颜色和目标颜色 color 相同时,直接返回原二维数组即可。

代码实现

classSolution{int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};public:voiddfs(vector<vector<int>>& image,int i,int j,int srcColor,int destColor){// 变色int m = image.size();int n = image[0].size(); image[i][j]= destColor;for(int k =0; k <4; k++){int x = i + dx[k];int y = j + dy[k];if(x >=0&& x < m && y >=0&& y < n && image[x][y]== srcColor)dfs(image, x, y, srcColor, destColor);}} vector<vector<int>>floodFill(vector<vector<int>>& image,int sr,int sc,int color){if(image[sr][sc]!= color)dfs(image, sr, sc, image[sr][sc], color);return image;}};

二、岛屿数量

题目解析

在这里插入图片描述

给定一个n*m的二维数组,其中1表示陆地、0表示海洋;

多个相邻的陆地可以看做是一座岛屿,要求计算网格中岛屿的数量

算法思路

遍历grid数组,遍历到陆地(1)并且该陆地没有和其他陆地形成岛屿(没有被BFS/DFS遍历过),就从该节点进行一次BFS/DFS遍历。

这样我们只需要统计在遍历grid时,进行BFS/DFS的次数即可。

这里使用 DFS 来接解决这道题

代码实现

classSolution{int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};bool vis[300][300];public:voiddfs(vector<vector<char>>& grid,int i,int j){ vis[i][j]=true;int m = grid.size(), n = grid[0].size();for(int k =0; k <4; k++){int x = i + dx[k];int y = j + dy[k];if(x >=0&& x < m && y >=0&& y < n &&!vis[x][y]&& grid[x][y]=='1')dfs(grid, x, y);}}intnumIslands(vector<vector<char>>& grid){int m = grid.size();int 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]){dfs(grid, i, j); ret++;}}}return ret;}};

三、岛屿的最大面积

题目解析

在这里插入图片描述

算法思路

这道题的结题思路也是和求岛屿数量大同小异;

还是遍历grid数组,在遍历到陆地并且该陆地没有和其他陆地组成岛屿。(遍历到1并且该位置没有被遍历过)

就从该位置进行一次BFS遍历(DFS也可以解决),并求出岛屿的面积;

然后统计岛屿面积的最大值 然后返回即可。

代码实现

classSolution{int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};bool vis[50][50];public:voiddfs(vector<vector<int>>& grid,int i,int j,int& cnt){++cnt; vis[i][j]=true;int m = grid.size();int n = grid[0].size();for(int k =0; k <4; k++){int x = i + dx[k];int y = j + dy[k];if(x >=0&& x < m && y >=0&& y < n && grid[x][y]==1&&!vis[x][y])dfs(grid, x, y, cnt);}}intmaxAreaOfIsland(vector<vector<int>>& grid){int ret =0, cnt =0;int 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]){dfs(grid, i, j, cnt); ret =max(ret, cnt); cnt =0;}}}return ret;}};

四、被围绕的区域

题目解析

在这里插入图片描述

算法思路

将所有不在边缘区域的 O 全部修改成 X

  • 先将在边缘的 O 区域进行标记(特殊处理,修改成其他无关字符)
  • 再将所有没有标记的 O 全部修改成 X
  • 最后,再复原边缘区域的 O

代码实现

classSolution{int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};bool vis[210][210];public:voiddfs(vector<vector<char>>& board,int i,int j,bool isChange =false){if(isChange) board[i][j]='X'; vis[i][j]=true;int m = board.size();int n = board[0].size();for(int k =0; k <4; k++){int x = i + dx[k];int y = j + dy[k];if(x >=0&& y >=0&& x < m && y < n &&!vis[x][y]&& board[x][y]=='O')dfs(board, x, y, isChange);}}voidsolve(vector<vector<char>>& board){// 处理边界int m = board.size(), n = board[0].size();for(int i =0; i < m; i++){if(board[i][0]=='O'&&!vis[i][0])dfs(board, i,0);if(board[i][n -1]=='O'&&!vis[i][n -1])dfs(board, i, n -1);}for(int i =0; i < n; i++){if(board[0][i]=='O'&&!vis[0][i])dfs(board,0, i);if(board[m -1][i]=='O'&&!vis[m -1][i])dfs(board, m -1, i);}// 修改内部for(int i =0; i < m; i++){for(int j =0; j < n; j++){if(board[i][j]=='O'&&!vis[i][j])dfs(board, i, j,true);}}}};

本篇文章到这里就结束了,感谢支持
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

Read more

【算法】前缀和

【算法】前缀和

🌈个人主页:秦jh_-ZEEKLOG博客 🔥 系列专栏:https://blog.ZEEKLOG.net/qinjh_/category_12862161.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=12862161&sharerefer=PC&sharesource=qinjh_&sharefrom=from_link     目录 【模板】一维前缀和  【模板】二维前缀和 前言 💬 hello! 各位铁子们大家好哇。              今日更新了前缀和的相关内容 🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝 【模板】一维前缀和 题目链接: DP34 【模板】一维前缀和  思路:

By Ne0inhk

算法笔记:洛谷 P1108 低价购买

洛谷:低价购买 1. 题目核心与难点 * 目标: 1 . 求最长下降子序列(LIS)的长度。 2 . 求达到该长度的不重复方案总数。 * 难点:方案去重。若两条路径数值序列完全一致(例如 10 8 6 和另外一组 10 8 6),即便位置不同,也只能算一种方案。 2.状态转移的定义 f [ i ] f[i] f[i]:以第 i i i 天价格结尾的最长下降子序列长度。 t [ i ] t[i] t[i]:以第 i i i 天价格结尾且长度为 f [ i

By Ne0inhk

轨迹数据压缩的Douglas-Peucker算法(附代码及原始数据)

机场出租车调度问题:数学建模实战解析 大家好!今天咱们来聊聊一个特别接地气的数学建模题目——机场的出租车调度问题。这是2019年全国大学生数学建模竞赛的C题,题目看着简单,实际上藏着不少玄机。咱们一起拆解这个题目,看看怎么用数学模型来解决现实生活中的难题。 问题背景:机场出租车的那些事儿 想象一下你刚从飞机下来,拖着行李箱走到出租车候客区,发现有两条队:一条是"短途专用通道",另一条是普通队。为什么会有这样的设计?背后其实是一套复杂的调度系统在运作。 题目给我们几个核心信息点: 1.大多数机场出租车司机会在"蓄车池"排队等待 2.机场管理人员会采集乘客目的地信息 3.对于短途乘客(比如目的地小于某个阈值d),会给司机"补偿"或安排他们优先接客 4.司机可以自主选择是否去"短途专用通道"排队 核心问题就是要我们设计一套合理的调度方案,在乘客等候时间、司机收益和机场管理效率之间找到平衡。 技术原理:排队论与博弈论的双剑合璧

By Ne0inhk
Flutter 三方库 diff_match_patch 鸿蒙文本比对拼接算法双向核心适配研判:毫秒解构海量字符差异区块建立丝滑无感知的协同编辑冲突强容错合并-适配鸿蒙 HarmonyOS ohos

Flutter 三方库 diff_match_patch 鸿蒙文本比对拼接算法双向核心适配研判:毫秒解构海量字符差异区块建立丝滑无感知的协同编辑冲突强容错合并-适配鸿蒙 HarmonyOS ohos

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 diff_match_patch 鸿蒙文本比对拼接算法双向核心适配研判:毫秒解构海量字符差异区块建立丝滑无感知的协同编辑冲突强容错合并机制 在文本编辑器、版本控制系统或协同办公应用中,快速、精准地找出两段文字之间的差异并生成补丁(Patch)是核心能力。diff_match_patch 库基于 Google 开发的高效算法,提供了业界领先的文本处理解决方案。本文将详解该库在 OpenHarmony 环境下的适配与实战。 前言 随着鸿蒙分布式能力的不断增强,多终端设备(手机、平板、电脑)之间的文档同步与协作编辑变得愈发频繁。直接传输整段文本不仅浪费带宽,且难以处理冲突。diff_match_patch 通过计算文本的最小增量,能够大幅提升鸿蒙分布式数据通信的效率。 一、原理解析 1.1 基础概念 diff_match_patch

By Ne0inhk