floodfill算法(一)

news2024/11/15 6:53:53

目录

一、图像渲染

1. 题目链接:733. 图像渲染

2. 题目描述:

3. 解法

🌴算法思路:

🌴算法代码:

二、岛屿数量

1. 题目链接:200. 岛屿数量

2. 题目描述:

3. 解法

🌴算法思路:

🌴算法流程:

🌴算法代码:

三、岛屿的最大面积

1. 题目链接:695. 岛屿的最大面积

2. 题目描述:

3. 解法(深搜dfs)

🌴算法思路:

🌴算法流程:

🌴算法代码:

四、被围绕的区域

1. 题目链接:130. 被围绕的区域

2. 题目描述:

3. 解法

🌴算法思路:

🌴算法代码:


一、图像渲染

1. 题目链接:733. 图像渲染

2. 题目描述:

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。

你也被给予三个整数 sr ,  sc 和 color 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。

为了完成 上色工作,从初始像素开始,记录初始坐标的 上下左右四个方向上 相邻且同色的像素点,接着再记录与这些像素点相邻且同色的新像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 color

最后返回 经过上色渲染后的图像 

示例 1:

输入: image = [[1,1,1],[1,1,0],[1,0,1]],sr = 1, sc = 1, color = 2
输出: [[2,2,2],[2,2,0],[2,0,1]]
解析: 在图像的正中间,(坐标(sr,sc)=(1,1)),在路径上所有符合条件的像素点的颜色都被更改成2。
注意,右下角的像素没有更改为2,因为它不是在上下左右四个方向上与初始点相连的像素点。

示例 2:

输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, color = 0
输出: [[0,0,0],[0,0,0]]

提示:

  • m == image.length
  • n == image[i].length
  • 1 <= m, n <= 50
  • 0 <= image[i][j], color < 216
  • 0 <= sr < m
  • 0 <= sc < n

3. 解法

🌴算法思路:

可以利用「深搜」或者「宽搜」,遍历到与该点相连的所有「像素相同的点」,然后将其修改成指定的像素即可。

递归函数设计:

参数:

a. 原始矩阵;

b. 当前所在的位置;

c. 需要修改成的颜色。

函数体:

a. 先将该位置的颜色改成指定颜色(因为我们的判断,保证每次进入递归的位置都是需要修改的位置);

b. 遍历四个方向上的位置:

  • 如果当前位置合法,并且与初始颜色相同,就递归进去。

🌴算法代码:

class Solution 
{
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
    int prev;
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
        if (image[sr][sc] == color) return image;

        m = image.size(), n = image[0].size();
        prev = image[sr][sc];
        dfs(image, sr, sc, color);
        return image;
    }
    void dfs(vector<vector<int>>& image, int i, int j, int color)
    {
        image[i][j] = color;

        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, color);
            }
        }
    }
};

二、岛屿数量

1. 题目链接:200. 岛屿数量

2. 题目描述:

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

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

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

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 '0' 或 '1'

3. 解法

🌴算法思路:

遍历整个矩阵,每次找到「⼀块陆地」的时候:

  • 说明找到「⼀个岛屿」,记录到最终结果 ret 里面;
  • 并且将这个陆地相连的所有陆地,也就是这块「岛屿」,全部「变成海洋」。这样的话,我们下次遍历到这块岛屿的时候,它「已经是海洋」了,不会影响最终结果。
  • 其中「变成海洋」的操作,可以利用「深搜」和「宽搜」解决,其实就是 733. 图像渲染 这道题~

这样,当我们,遍历完全部的矩阵的时候, ret 存的就是最终结果。

🌴算法流程:

  1. 初始化 ret = 0 ,记录目前找到的岛屿数量;
  2. 双重循环遍历二维网格,每当遇到一块陆地,标记这是一个新的岛屿,然后将这块陆地相连的陆地全部变成海洋。

递归函数的设计:

1. 把当前格子标记为水;

2. 向上、下、左、右四格递归寻找陆地,只有在下标位置合理的情况下,才会进入递归:

  • 下一个位置的坐标合理;
  • 并且下一个位置是陆地。

🌴算法代码:

class Solution 
{
    vector<vector<bool>> vis;
    int m, n;
public:
    int numIslands(vector<vector<char>>& grid) 
    {
        m = grid.size(), n = grid[0].size();
        vis = vector<vector<bool>>(m, vector<bool>(n));

        int ret = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
            {
                if (!vis[i][j] && grid[i][j] == '1')
                {
                    ret++;
                    dfs(grid, i, j);
                }
            }
        
        return ret;
    }

    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    void dfs(vector<vector<char>>& grid, int i, int j)
    {
        vis[i][j] = true;
        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);
            }
        }
    }
};

三、岛屿的最大面积

1. 题目链接:695. 岛屿的最大面积

2. 题目描述:

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

示例 1:

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。

示例 2:

输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

3. 解法(深搜dfs)

🌴算法思路:

1. 遍历整个矩阵,每当遇到⼀块土地的时候,就用「深搜」或者「宽搜」将与这块土地相连的「整个岛屿」的面积计算出来。

2. 然后在搜索得到的「所有的岛屿面积」求⼀个「最大值」即可。

3. 在搜索过程中,为了「防止搜到重复的土地」:

  • 可以开一个同等规模的「布尔数组」,标记一下这个位置是否已经被访问过;
  • 也可以将原始矩阵的 1 修改成 0 ,但是这样操作会修改原始矩阵。

🌴算法流程:

主函数内:

a. 遍历整个数组,发现⼀块没有遍历到的土地之后,就用 dfs ,将与这块土地相连的岛屿的面积求出来;

b. 然后将面积更新到最终结果 ret 中。

深搜函数 dfs 中:

a. 能够进到 dfs 函数中,说明是一个没遍历到的位置;

b. 标记一下已经遍历过,设置一个变量 S = 1 (当前这个位置的面积为 1 ),记录最终的面积;

c. 上下左右遍历四个位置:

  • 如果找到⼀块没有遍历到的土地,就将与这块土地相连的岛屿面积累加到 S 上;

d. 循环结束后, S 中存的就是整块岛屿的面积,返回即可。

🌴算法代码:

class Solution 
{
    vector<vector<bool>> vis;
    int m, n;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int count;
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) 
    {
        m = grid.size(), n = grid[0].size();
        vis = vector<vector<bool>>(m, vector<bool>(n));

        int ret = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
            {
                if (!vis[i][j] && grid[i][j] == 1)
                {
                    count = 0;
                    dfs (grid, i, j);
                    ret = max(ret, count);
                }
            }
        
        return ret;
    }
    void dfs (vector<vector<int>>& grid, int i, int j)
    {
        count++;
        vis[i][j] = true;
        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 && !vis[x][y] && grid[x][y] == 1)
            {
                dfs (grid, x, y);
            }
        }
    }
};

四、被围绕的区域

1. 题目链接:130. 被围绕的区域

2. 题目描述:

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' 组成,捕获 所有 被围绕的区域

  • 连接:一个单元格与水平或垂直方向上相邻的单元格连接。
  • 区域:连接所有 'O' 的单元格来形成一个区域。
  • 围绕:如果您可以用 'X' 单元格 连接这个区域,并且区域中没有任何单元格位于 board 边缘,则该区域被 'X' 单元格围绕。

通过将输入矩阵 board 中的所有 'O' 替换为 'X' 来 捕获被围绕的区域

示例 1:

输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]

输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]

解释:

在上图中,底部的区域没有被捕获,因为它在 board 的边缘并且不能被围绕。

示例 2:

输入:board = [["X"]]

输出:[["X"]]

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j] 为 'X' 或 'O'

3. 解法

🌴算法思路:

正难则反

        可以先利用 dfs 将与边缘相连的 '0' 区域做上标记,然后重新遍历矩阵,将没有标记过的 '0' 修改成 'X' 即可。

🌴算法代码:

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();

        // 1.把与边界相连的连通块 'O' 修改成 '.'
        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);
        }

        // 2.还原
        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);
            }
        }
    }
};

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

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

相关文章

FinLex An effective use of word embeddings for financial lexicon generation

FinLex: An effective use of word embeddings for financial lexicon generation 论文阅读 文章目录 FinLex: An effective use of word embeddings for financial lexicon generation 论文阅读 AbstractMethodology具体词表例子LM 词列表与 FinLex 词列表 词列表在分类任务中…

网络安全学习(二)Netdiscover

Netdiscover是一款网络扫描工具&#xff08;kali中有这个工具&#xff09;&#xff0c;它可以扫描本地网络主机&#xff0c;它借助ARP协议实施主机发现&#xff0c;长这个样子。 点击打开&#xff0c;进入命令行。 首先查看本机的IP地址&#xff0c;命令为ifconfig&#xff0c…

TAG:BladeLLM 的纯异步推理架构

作者&#xff1a;张子鹏 PAI引擎团队 随着 GQA/MLA/MoE 等模型结构不断发展&#xff0c;大语言模型的推理逐步解除了显存限制&#xff0c;逐渐向着高并发、高吞吐的方向发展。推理引擎的运行时开销也变得不可忽视。主流 LLM 推理框架的运行时开销大致来自&#xff1a; Python …

【MySQL学习】基础指令全解:构建你的数据库技能

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;MySQL学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 引言 下面的操作都是在windows 的…

AT89C51 Intel HEX手工结构分析 反汇编工具

在不查询格式情况下分析确定 Intel HEX 格式 Hex文件内容 :0300000002090BE7 :0C090B00787FE4F6D8FD7581080208F63C :01091700419E :1008F60078087C007D007BFF7A0979177E007F01EE :050906001208D080FE84 :10080000E709F608DFFA8046E709F208DFFA803EDA :1008100088828C83E709F0…

C++基础面试题 | C++中的构造函数可以是虚函数吗? C++中的析构函数一定要是虚函数吗?

文章目录 问题一&#xff1a;在C中&#xff0c;构造函数不能是虚函数。问题二&#xff1a;析构函数不一定需要声明为虚函数&#xff0c;但在多态环境下&#xff0c;建议一定将其声明为虚函数。示例虚函数总结 问题一&#xff1a;在C中&#xff0c;构造函数不能是虚函数。 这是…

PMP--一模--解题--81-90

文章目录 4.整合管理81、 [单选] 一位先前不活跃的干系人参与程度突然增加&#xff0c;这种意外的参与导致了一些变更请求。项目经理应该做什么&#xff1f; 4.整合管理82、 [单选] 公司的新产品系列将在两个月内发布&#xff0c;95%的项目任务均已完成。但是&#xff0c;管理层…

二分算法——优选算法

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;游戏、数据结构、c语言基础、c学习、算法 本章我们来学习的是二分查找算法&#xff0c;二分算法的应用非常广泛&#xff0c;不仅限于数组查找&#xff0c;还可以用于解决各种搜索问题、查找极值问题等。在数据结构和算…

无人机飞手培训机构组建及市场分析

飞手培训机构是专门为培养无人机飞行员&#xff08;飞手&#xff09;而设立的教育机构。这些机构通过提供专业的培训课程&#xff0c;帮助学员掌握无人机飞行技术、了解相关法规、提升实战能力&#xff0c;并最终获得相关证书&#xff0c;以便在航拍摄影、农业植保、物流配送、…

MS SQL Server 实战 排查多列之间的值是否重复

目录 需求 范例运行环境 数据样本设计 功能实现 上传EXCEL文件到数据库 SQL语句 小结 需求 在日常的应用中&#xff0c;排查列重复记录是经常遇到的一个问题&#xff0c;但某些需求下&#xff0c;需要我们排查一组列之间是否有重复值的情况。比如我们有一组题库数据&…

django实现开发、测试、生产环境配置区分

文章目录 一、为什么要区分开发 (dev)、测试 (test) 和生产 (prod) 环境二、django项目如何通过配置实现环境配置的区分1、针对不同的环境创建不同的设置文件settings.py2、在设置文件中根据需要进行配置区分3、根据不同的环境运行使用不同的设置文件 任何实际的软件项目中都要…

使用Python打造全自动wx好友添加器:批量操作,高效省时的社交神器

在现代的数字营销和社交扩展中&#xff0c;自动化操作可以显著提高效率。尤其是wx这种广泛使用的即时通讯工具&#xff0c;很多用户有批量添加好友的需求&#xff0c;但手动操作费时费力。本教程将详细介绍如何使用 Python 开发一个自动化工具&#xff0c;帮助你批量添加wx好友…

宏任务和微任务+超全面试真题(持续更新ing

概念 微任务和宏任务是在异步编程中经常使用的概念&#xff0c;用于管理任务的执行顺序和优先级。 宏任务&#xff1a;setTimeout, setInterval&#xff0c;I/O 操作和 UI 渲染等。微任务&#xff1a; Promise 回调、async/await等 微任务通常比宏任务具有更高的优先级。 执…

C#基础(11)函数重载

前言 前面我们已经完成了ref和out补充知识点的学习&#xff0c;以及函数参数相关的学习&#xff0c;今天便再次为函数补充一个知识点&#xff1a;函数重载。 函数重载是指在同一个作用域中&#xff0c;可以有多个同名函数&#xff0c;但参数列表不同。它的发展可以追溯到早期…

【Chrome】开发一个Chrome扩展以及常见问题的解决方案

前言 本文介绍开发chrome扩展很重要的几种操作&#xff0c;如&#xff1a;操作网页dom、发送请求、渲染弹层、不同沙盒环境的通信方式、扩展与网页的通信方式、遇到iframe时的操作等。最终会提供一个简单的案例&#xff0c;其中涵盖了上述操作。 还有一些本人相关文章&#x…

HashMap 详解

哈希表 哈希表又叫散列表&#xff0c;或者映射、字典都是指哈希表&#xff0c;哈希表是通过关键码映射到数组的某个位置来访问的数据结构&#xff0c;实现这个映射的函数就是哈希函数&#xff0c;哈希表结合了数组和链表的优点&#xff0c;查找和插入操作的时间复杂度都是O(1)。…

MySQL篇(高级字符串函数/正则表达式)(持续更新迭代)

目录 讲点一&#xff1a;高级字符串函数 一、简介 二、常见字符串函数 1. CONCAT() 2. SUBSTRING() 3. LENGTH() 4. REPLACE() 5. TRIM() 6. UPPER() 7. LOWER() 8. LEFT() 9. RIGHT() 10. INSTR() 11. LENTH(str) 讲点二&#xff1a;正则表达式 一、简介 二、…

AIGC实战——多模态模型Flamingo

AIGC实战——多模态模型Flamingo 0. 前言1. Flamingo 架构2. 视觉编码器3. Perceiver 重采样器4. 语言模型5. FIamingo 应用小结系列链接 0. 前言 我们已经学习了文本生成图像模型 DALL.E 2&#xff0c;在本节中&#xff0c;我们将探索另一种多模态模型 Flamingo&#xff0c;它…

学习使用在windows系统上安装nodejs以及环境配置图文教程整理

学习使用在windows系统上安装nodejs以及环境配置图文教程整理 Node.js 介绍Node.js 安装1、Node.js下载2、Node.js安装3、Node.js测试4、Node.js安装目录5、Node.js环境变量配置6、配置镜像站&#xff0c;提升速度7、检查镜像站配置8、测试环境变量是否生效9、安装cnpm Node.js…

jwt报错,位置:找不到符号 parseClaimsJws(java.lang.String)

报错显示如图 报错信息为&#xff1a; E:\idea\project\tlias\src\main\java\org\itheima\tlias\utils\JwtUtils.java:36:17 java: 找不到符号 符号: 方法 parseClaimsJws(java.lang.String) 位置: 接口 io.jsonwebtoken.JwtParserBuilder 解决办法 项目使用的是最新…