FloodFill(洪水灌溉)算法专题——DFS深搜篇
目录
1、图像渲染
1.1 算法原理
1.2 算法代码
2、岛屿数量
2.1 算法原理
2.2 算法代码
3、岛屿的最大面积
3.1 算法原理
3.2 算法代码
4、被围绕的区域
4.1 算法原理
4.2 算法代码
5、太平洋大西洋水流问题
5.1 算法原理
5.2 算法代码
6、扫雷游戏
6.1 算法原理
6.2 算法代码
7、衣橱整理 (原:面试题 13. 机器人的运动范围 )
7.1 算法原理
7.2 算法代码
1、图像渲染
. - 力扣(LeetCode)
1.1 算法原理
- 从(sr,sc)位置开始上下左右暴搜,将区域中符合条件的值修改为color。
- 细节问题:当 color == image[sr][sc]时,不需修改,直接返回即可。

1.2 算法代码
class Solution {int[] dx, dy;int[][] image;int color;int n, m;int val;public int[][] floodFill(int[][] image_, int sr, int sc, int color_) {if(color_ == image_[sr][sc]) return image_;image = image_;val = image[sr][sc];color = color_;n = image.length;m = image[0].length;dx = new int[]{-1, 1, 0, 0};dy = new int[]{0, 0, -1, 1};image[sr][sc] = color;dfs(sr, sc);return image;}public void dfs(int i, int j) {for(int k = 0; k < 4; k++) {int x = i + dx[k];int y = j + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && image[x][y] == val) {image[x][y] = color;dfs(x, y);}}}
}
2、岛屿数量
. - 力扣(LeetCode)
2.1 算法原理
全局变量:
- boolean[][] check;//是否来过
- int ret;//返回值
- int[] dx;//横坐标上下左右
- int[] dy;//纵坐标上下左右
思想:
- 遍历矩阵,每次来到新的'1'区域,将这个区域中的所有'1'位置做好标记(check置为false),ret++
- 返回ret
2.2 算法代码
class Solution {int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};boolean[][] check;int ret;int m, n;public int numIslands(char[][] grid) {m = grid.length;n = grid[0].length;check = new boolean[m][n];for(int i = 0; i < m ; i++) {for(int j = 0; j < n; j++) {if(check[i][j] == false && grid[i][j] == '1') {ret++;check[i][j] = true;dfs(grid, i, j);}}}return ret;}public void dfs(char[][] grid, int i, int j) {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' && !check[x][y]) {check[x][y] = true;dfs(grid, x, y);}}}
}
3、岛屿的最大面积
. - 力扣(LeetCode)
3.1 算法原理
与上题基本一致,选出面积最大值即可:
- 暴搜
- count记录每块陆地的最大面积(每次进入dfs,count++)
- ret记录所有陆地的最大面积(选出count的最大值)

3.2 算法代码
class Solution {int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};boolean[][] check;int ret;int m, n;int count;public int maxAreaOfIsland(int[][] grid) {m = grid.length;n = grid[0].length;check = new boolean[m][n];for(int i = 0; i < m ; i++) {for(int j = 0; j < n; j++) {if(check[i][j] == false && grid[i][j] == 1) {count = 0;check[i][j] = true;dfs(grid, i, j);//统计一块陆地的面积ret = Math.max(ret, count);}}}return ret;}public void dfs(int[][] grid, int i, int j) {count++; 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 && !check[x][y]) {check[x][y] = true;dfs(grid, x, y);}}}
}
4、被围绕的区域
. - 力扣(LeetCode)
4.1 算法原理
本题采用“正难则反”法则,既然我们无法区分边缘区域与内部区域,那么就先对矩阵的边缘区域进行操作:
- 对边缘区域的所有'O'区域进行深搜,修改为'.'
- 此时边缘区域的'O'已全部修改为'.',内部区域的'O'仍为'O'
- 再遍历整个矩阵,'.'重新修改为'O'(边缘区域的'O'),'O'则修改为'X'(内部区域的'O')

4.2 算法代码
class Solution {int m, n;int[] dx = { 1, -1, 0, 0 };int[] dy = { 0, 0, 1, -1 };public void solve(char[][] board) {m = board.length;n = board[0].length;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {//把边缘区域的O置为.if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') {board[i][j] = '.';dfs(board, i, j);}}}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';}}public void dfs(char[][] board, int i, int j) {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 && board[x][y] == 'O') {board[x][y] = '.';dfs(board, x, y);}}}
}
5、太平洋大西洋水流问题
. - 力扣(LeetCode)
5.1 算法原理
本题仍采用“正难则反”原则:
- 从海岸反向记录可流入海洋的位置
- 分别标记哪些位置可流入太平洋(boolean[][] pac),可流入则标为true
- 分别标记哪些位置可流入大西洋(boolean[][] atl),可流入则标为true
- pac、atl中均为true的位置,说明均可流入两大海洋。

5.2 算法代码
class Solution {int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};int m, n;public List<List<Integer>> pacificAtlantic(int[][] heights) {m = heights.length;n = heights[0].length;boolean[][] pac = new boolean[m][n];//标记太平洋可流入的位置boolean[][] atl = new boolean[m][n];//标记大西洋可流入的位置//pacfor(int j = 0; j < n; j++) dfs(heights, 0, j, pac);for(int i = 0; i < m; i++) dfs(heights, i, 0, pac);//atlfor(int j = 0; j < n; j++) dfs(heights, m - 1, j, atl);for(int i = 0; i < m; i++) dfs(heights, i, n - 1, atl);//都可流入的位置List<List<Integer>> ret = new ArrayList<>();for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if(pac[i][j] && atl[i][j]) {List<Integer> list = new ArrayList<>();list.add(i);list.add(j);ret.add(list);}}}return ret;}public void dfs(int[][] heights, int i, int j, boolean[][] check) {check[i][j] = true;int cur = heights[i][j];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 && check[x][y] == false && heights[x][y] >= cur) {dfs(heights, x, y, check);}}}
}
6、扫雷游戏
. - 力扣(LeetCode)
6.1 算法原理
本题主要节目就是dfs及回溯:如果相邻没有地雷的空方块被挖出,则将其上下左右及四角方向全部递归揭露所有和其相邻的未挖出的方块,直至相邻的方块的周围有地雷,则将周围有地雷的方块标为地雷的数量。
对于斜方向上,我们只需在dx和dy数组上的对应位置上加上相应值即可。

6.2 算法代码
class Solution {char[][] board;int[] dx = {0, 0, 1, -1, -1, -1, 1, 1};int[] dy = {1, -1, 0, 0, -1, 1, -1, 1};int m, n;public char[][] updateBoard(char[][] board_, int[] click) {board = board_;m = board.length;n = board[0].length;int sx = click[0], sy = click[1];char ch = board[sx][sy];if(ch == 'M') {board[sx][sy] = 'X';return board;}if(ch == 'B') return board;dfs(sx, sy);return board;}public void dfs(int i, int j) {int count = 0;for(int k = 0; k < 8; k++) {int x = i + dx[k];int y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'M') {count++;}}if(count != 0) {//周围有地雷board[i][j] = (char)(count + '0');return;}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(x, y);}}}}
}
7、衣橱整理 (原:面试题 13. 机器人的运动范围 )
. - 力扣(LeetCode)
7.1 算法原理
直接dfs洪水灌溉,需要注意的是:
- 每个位置不能重复进入
- 横纵下标的每个位的数值之和不能超过cnt
7.2 算法代码
class Solution {int ret;int[] dx = { 1, -1, 0, 0 };int[] dy = { 0, 0, 1, -1 };int m, n;boolean[][] check;public int wardrobeFinishing(int m_, int n_, int cnt) {m = m_;n = n_;check = new boolean[m][n];dfs(0, 0, cnt);return ret;}public void dfs(int i, int j, int cnt) {check[i][j] = true;ret++;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 && !check[x][y] && isRight(x, y, cnt)) {dfs(x, y, cnt);}}}public boolean isRight(int x, int y, int cnt) {int sum = 0;while (x != 0) {sum += x % 10;x /= 10;}while (y != 0) {sum += y % 10;y /= 10;}return sum <= cnt;}
}
END
相关文章:
FloodFill(洪水灌溉)算法专题——DFS深搜篇
目录 1、图像渲染 1.1 算法原理 1.2 算法代码 2、岛屿数量 2.1 算法原理 2.2 算法代码 3、岛屿的最大面积 3.1 算法原理 3.2 算法代码 4、被围绕的区域 4.1 算法原理 4.2 算法代码 5、太平洋大西洋水流问题 5.1 算法原理 5.2 算法代码 6、扫雷游戏 6.1 算法原理…...
直播标准权威发布,阿里云RTS获首批卓越级评估认证
近期举办的2024“可信云大会”上,中国信通院正式发布了2024年上半年音视频领域最新评估结果。阿里云超低延时直播,以首批卓越级,通过中国信通院超低延时直播性能及服务质量分级测试。 标准发布,权威量化直播体验质量 从直播元年发…...
iOS 知识点记录
王巍 博客地址:OneVs Den git地址:onevcat (Wei Wang) GitHub 江湖人称喵神,目前就职于line。喵神的博客涉及方面比较广, 有Obejctive-C, Swift, SwiftUI, Unity等等。博客内容很有深度,非常值得关注。 戴铭 博客地址:戴铭的博客 git地址:ming1016 (戴铭) GitHub 《i…...
C++系列-STL中搜索相关算法
STL中search相关算法 💢search相关算法💢💢search算法举例💢💢search_n算法举例💢💢binary_search算法举例 💢 lower_bound💢 upper_bound💢 lower_bound和up…...
5.C++程序中的注释
我们来看上节所写的程序 #include <iostream> using namespace std;void prnt() //打印A {cout << "printA" << endl; }int main() {prnt();return 0; } 上面的程序中“//打印A”,表示说明当前函数是打印内容的函数,具体…...
com.kingbase8.util.KSQLException: ERROR: permission denied for table xxx
前言 在信创改造中,数据库替换为国产数据库是不可缺少的一部分。而可替换选项中多数选项无非是人大金仓和达梦数据库二选一。本文将介绍人大金仓在使用过程的问题以及解决办法。 问题 在使用人大金仓数据库后,程序运行报错 com.kingbase8.util.KSQLEx…...
开发小程序
由于之前购入的阿里云ECS放着落灰,碰巧又看到个有趣的项目,于是就做了个生成头像的小程序…由于第一次完整发布小程序,记录一下遇到的问题 小程序名称:靓仔创意头像 😂 关于小程序 接口请求,在开发过程中…...
JS考核答案
1.请简述var, let, const的区别? (1)块级作用域:块作用域由 { }包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中的两个问题: 内层变量可能覆盖外层变量 用来计数的…...
高德地图2.0 绘制、编辑多边形覆盖物(电子围栏)
1. 安装 npm i amap/amap-jsapi-loader --save移步:官方文档 2. map组件封装 <script lang"ts" setup> import AMapLoader from amap/amap-jsapi-loader import { onMounted, ref } from vue import { propTypes } from /utils/propTypesdefineO…...
MySQL底层为什么选择用B+树作为索引
首先,我们来想想为什么这么多数据结构,为什么要用树这种数据结构? 众多的数据结构在逻辑层面可分为:线性结构 和 非线性结构。 线性结构有:数组、链表,基于它们衍生出的有哈希表(哈希表也称散…...
MATLAB系列05:自定义函数
MATLAB系列05:自定义函数 5. 自定义函数5.1 MATLAB函数简介5.2 在MATLAB中传递变量:按值传递机制5.3 选择性参数5.4 用全局内存分享数据5.5 在函数两次调用之间本地数据的存储5.6 函数的函数(function functions)5.7 子函数和私有函数5.8 总结 5. 自定义…...
C++速通LeetCode简单第20题-多数元素
方法一:暴力解法,放multiset中排序,然后依次count统计,不满足条件的值erase清除。 class Solution { public:int majorityElement(vector<int>& nums) {int ans 0;multiset<int> s;for(int i 0;i < nums.s…...
回收站永久删除的文件还能恢复吗?教你恢复技巧
在数字时代,电脑是我们工作、学习和娱乐的重要工具。然而,随着我们对电脑的频繁使用,误删文件的情况也时有发生。当我们在回收站中不小心永久删除了某个重要文件时,内心可能会充满焦虑和疑惑:这些文件还能恢复吗&#…...
Python Web 微服务架构全面解析与实战指南
Python Web 微服务架构全面解析与实战指南 目录 🏗️ 微服务基础概念 微服务架构与单体架构的对比微服务的优点与挑战 🔄 服务间通信 使用REST、gRPC或消息队列实现服务通信API网关的使用(如Kong、Traefik) 🔍 服务…...
SEAFARING靶场漏洞攻略
寻找漏洞 一,我们打开页面 第一个漏洞 xss漏洞 1.在登录页面显示有弹窗 第二个漏洞 sql注入漏洞 1.在输入框的地方输入-1 union select 1,2,3#我们来查看他的回显点 2.查看数据库表名 -1 union select 1,database(),3# 3.查看表名 -1 union select 1,2,group…...
ROS 编程入门的介绍
2.1 创建 ROS 功能包 ROS(Robot Operating System)是一种开源的机器人软件框架,广泛用于机器人开发中。通过使用 ROS,开发者可以轻松创建和管理机器人应用程序。在本节中,我们将介绍如何创建一个 ROS 功能包并实现一些…...
第十一章 抽象类与接口
一、抽象类和抽象方法 抽象类:使用abstract修饰的类 抽象方法:在类中没有方法体的方法,称为抽象方法,抽象方法用abstract修饰 抽象类中可以没有抽象方法,包含抽象方法的类必是抽象类 如果子类没有实现父类中的全部…...
请问企业的八大金刚系统是哪些?有什么共同点和区别?
我的理解的八大金刚包括:MES、ERP、WMS、OMS、CRM、SCM、SRM、PLM。 这些系统的主要功能及运用领域是哪些方面?他们互相之前有什么区别?选择时哪些是企业可能根据自身需求选择的必选项目或可选项目? 由于某些系统的必选性取决于企业的具体业…...
【入门】配置 Java 应用程序的完整指南
前言: Java 是一种广泛使用的编程语言,具备跨平台的特性,使得其应用程序可以在多种环境中高效运行。本文将介绍如何将 Java 应用程序从开发环境部署到生产环境,确保其能够稳定、稳定地运行运行。 确定运行环境 Java程序可以运行…...
flutter widget 设置GestureDetector点击无效
有可能是被上层的widget挡住了,虽然你看得到这个widget,但是操作不到。使用相对布局Stack要特别注意,这种布局会和Android一样,先写的布局放在下层,后写的,如果范围较大的话,会盖在之前的widget…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

