跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

Flood Fill 算法实战:图像渲染与岛屿问题解析

Flood Fill 算法基于深度优先搜索或广度优先搜索遍历连通区域。本文结合图像渲染、岛屿数量、最大面积及被围绕区域四个经典题目,演示如何利用 DFS 标记访问状态、统计连通分量及计算面积。重点讲解边界处理与颜色替换逻辑,提供完整的 C++ 代码实现与思路分析。

嘘发布于 2026/3/24更新于 2026/10/2583 浏览
Flood Fill 算法实战:图像渲染与岛屿问题解析

Flood Fill 算法核心思想

Flood Fill(洪水填充)是一种基于连通性遍历的算法,常用于确定多维数组中给定节点所属的区域。其核心逻辑非常直观:

  • 种子点扩散:从初始像素出发,向四周扩展。
  • 条件匹配:仅填充颜色相同且相邻的像素。
  • 状态标记:记录已访问位置,避免死循环或重复计算。

这类问题通常使用深度优先搜索(DFS)或广度优先搜索(BFS)实现。下面结合四个经典题目,演示如何灵活应用这一思路。

一、图像渲染

题目描述

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

图像渲染示意图

解题思路

这道题的逻辑其实很直观,本质上就是一次标准的 DFS 遍历。需要注意一个边界情况:如果起始位置的颜色已经等于目标颜色,直接返回原数组即可,无需任何操作。

代码实现

class Solution {
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
public:
    void dfs(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 ( k = ; k < ; k++) {
             x = i + dx[k];
             y = j + dy[k];
             (x >=  && x < m && y >=  && y < n && image[x][y] == srcColor) {
                (image, x, y, srcColor, destColor);
            }
        }
    }

    vector<vector<>> (vector<vector<>>& image,  sr,  sc,  color) {
         (image[sr][sc] != color) {
            (image, sr, sc, image[sr][sc], color);
        }
         image;
    }
};
int
0
4
int
int
if
0
0
dfs
int
floodFill
int
int
int
int
if
dfs
return

二、岛屿数量

题目描述

给定一个由 '1'(陆地)和 '0'(海洋)组成的二维网格,统计其中岛屿的数量。多个相邻的陆地视为同一座岛屿。

岛屿数量示意图

解题思路

遍历整个网格,一旦遇到未被访问过的陆地('1'),就说明发现了一座新岛屿。此时启动一次 DFS 或 BFS,将该岛屿所有相连的陆地标记为已访问。最终统计启动搜索的次数即为岛屿总数。

这里采用 DFS 来实现。

代码实现

class Solution {
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    bool vis[300][300];
public:
    void dfs(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);
            }
        }
    }

    int numIslands(vector<vector<char>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int ret = 0;
        memset(vis, 0, sizeof(vis));
        
        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;
    }
};

三、岛屿的最大面积

题目描述

在同样的网格中,这次要求计算每个岛屿的面积,并返回最大面积值。

岛屿最大面积示意图

解题思路

思路与上一题类似,区别在于每次 DFS 遍历时需要累加当前岛屿的格子数。遍历过程中维护一个全局最大值,遍历结束后返回该值即可。

代码实现

class Solution {
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    bool vis[50][50];
public:
    void dfs(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);
            }
        }
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int ret = 0, cnt = 0;
        int m = grid.size(), n = grid[0].size();
        memset(vis, 0, sizeof(vis));
        
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && !vis[i][j]) {
                    cnt = 0;
                    dfs(grid, i, j, cnt);
                    ret = max(ret, cnt);
                }
            }
        }
        return ret;
    }
};

四、被围绕的区域

题目描述

给定一个 m * n 的二维字符矩阵,将所有被 'X' 包围的 'O' 替换为 'X'。注意:位于边界的 'O' 不会被替换。

被围绕的区域示意图

解题思路

直接寻找内部被包围的 'O' 比较困难,不如换个角度:先找出所有不会被替换的 'O'。这些 'O' 必然与边界上的 'O' 相连。

具体步骤如下:

  1. 遍历四条边界,对遇到的 'O' 进行 DFS 标记(例如改为临时字符 '#')。
  2. 遍历整个矩阵,将剩余的 'O' 替换为 'X'。
  3. 最后将之前标记的 '#' 还原为 'O'。

代码实现

class Solution {
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    bool vis[210][210];
public:
    void dfs(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);
            }
        }
    }

    void solve(vector<vector<char>>& board) {
        int m = board.size(), n = board[0].size();
        memset(vis, 0, sizeof(vis));
        
        // 处理边界,标记不与内部连通的 O
        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);
                }
            }
        }
    }
};

以上便是 Flood Fill 算法在几个典型场景中的应用。掌握这种'连通区域遍历'的思维模式,对于解决类似的图论问题会有很大帮助。

目录

  1. Flood Fill 算法核心思想
  2. 一、图像渲染
  3. 题目描述
  4. 解题思路
  5. 代码实现
  6. 二、岛屿数量
  7. 题目描述
  8. 解题思路
  9. 代码实现
  10. 三、岛屿的最大面积
  11. 题目描述
  12. 解题思路
  13. 代码实现
  14. 四、被围绕的区域
  15. 题目描述
  16. 解题思路
  17. 代码实现

更多推荐文章

查看全部
  • Linux 容器化核心原理:Namespace 隔离与 cgroups 资源控制及 LXC 实战
  • AI 大模型开发:程序员的机遇与挑战
  • Mac Mini M4 本地部署大模型:Ollama、Llama 与 ComfyUI 环境搭建
  • Llama-2-7B 在昇腾 NPU 上的性能测评与部署实践
  • Whisper v0.2 语音转文字工具安装与使用指南
  • AI 绘画在商业设计中的实战应用与版权解析
  • Python 爬虫与数据分析实战:以斗鱼直播为例
  • 数据结构入门:基于数组的栈结构实现详解
  • 电力线场景下无人机返航的尺度不变逼近检测器
  • Stable Diffusion v1.5 风格化图像生成实战与 Prompt 技巧分享
  • DeerFlow 2.0 实战指南:生产级 AI Agent 框架的 Docker 化部署与并行编排
  • 2026 年主流 AI 生成 PPT 工具实测与横向对比
  • PromptPilot 重构 AI 创作逻辑:企业级支撑与创意角色扮演实战
  • 从麦克斯韦到无人机:有感 FOC 与无感 FOC 的深度解析
  • C++ 哈希表封装:模拟实现 unordered_map 和 unordered_set
  • 工业大模型落地难点分析:数据、算力与行业壁垒
  • Transformer 与大模型应用开发核心指南
  • Ubuntu 24.04 安装与配置 OpenClaw 实战指南
  • 从 Python 到 OpenClaw:构建本地 AI 助理的实战路径
  • 递归算法实战:汉诺塔与合并有序链表详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online