前言
Flood Fill(也称为种子填充算法)是一种用于确定连接到多维数组中给定节点的区域的算法
核心思想
- 从起点开始:从一个初始像素(种子点)开始
- 扩散填充:向四周(通常为4方向或8方向)扩展
- 条件匹配:只填充与种子点颜色相同且相邻的像素
- 避免重复:标记已访问的位置,防止重复处理
一、图像渲染
题目解析

给定一个 m*n 的二维数组,从起始位置 [sr,sc] 开始,将从起始位置的 上下左右 四个方向上 相邻且与起始位置初始颜色相同的像素点进行染色,直到没有其他原始颜色的相邻像素。
算法思路
这道题整体还是非常简单的,从起始位置开始,进行一次深度优先遍历 DFS 即可。
注意 :当起始位置[sr, sc]的颜色和目标颜色 color 相同时,直接返回原二维数组即可。
代码实现
cpp
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 (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 来接解决这道题
代码实现
cpp
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;
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也可以解决),并求出岛屿的面积;
然后统计岛屿面积的最大值 然后返回即可。
代码实现
cpp
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();
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
代码实现
cpp
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();
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