前言:
FloodFill是一直从指定起点出发,通过递归/迭代遍历相邻且满足条件的算法。
核心原理
- 以起始位置为中心,向上下左右等相邻方向扩散。
- 只遍历与起始点相邻且满足条件的元素,遇到边界(属性不同)则停止。
这里使用BFS算法,来解决这类问题。
BFS也就是广度优先遍历,代码实现通常要使用队列结构,类似与层序遍历的操作。
一、图像渲染
题目解析

这道题给定一个n*m的二维数组,以及起点坐标(sr,sc),以及要修改的颜色color,我们要从(sr,sc)开始对其相邻(上、下、左、右)且与该位置颜色相同(对应位置的值相等)进行染色。
最后返回染色号的数组。
算法思路
这道题还是非常简单的,我们只需要从(sr,sc)开始,进行一次BFS,在遍历的过程中进行染色即可。
这道题也可以使用
DFS、递归遍历来解决。
代码实现
cpp
class Solution {
public:
typedef pair<int, int> PII;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc,
int color) {
int prev = image[sr][sc];
if (prev == color)
return image;
int n = image.size();
int m = image[0].size();
queue<PII> pq;
pq.push({sr, sc});
while (pq.size() > 0) {
auto [x, y] = pq.front();
pq.pop();
image[x][y] = color;
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a >= 0 && a < n && b >= 0 && b < m && image[a][b] == prev)
pq.push({a, b});
}
}
return image;
}
};
二、岛屿数量
题目解析

给定一个n*m的二维数组,其中1表示陆地、0表示海洋;
多个相邻的陆地可以看做是一座岛屿,要求计算网格中岛屿的数量。
算法思路
这道题也是一道典型的BFS/DFS的题目了,整体思路:
遍历grid数组,遍历到陆地(1)并且该陆地没有和其他陆地形成岛屿(没有被BFS/DFS遍历过),就从该节点进行一次BFS/DFS遍历。
这样我们只需要统计在遍历grid时,进行BFS/DFS的次数即可。
这里使用BFS来解决这道题问题。
代码实现
cpp
class Solution {
public:
typedef pair<int, int> PII;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool vis[310][310] = {false};
int numIslands(vector<vector<char>>& grid) {
int n = grid.size();
int m = grid[0].size();
int ret = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '1' && vis[i][j] == false) {
ret++;
bfs(grid, i, j);
}
}
}
return ret;
}
void bfs(vector<vector<char>>& grid, int i, int j) {
// bfs遍历
int n = grid.size();
int m = grid[0].size();
queue<PII> q;
q.push({i, j});
vis[i][j] = true;
while (q.size()) {
// 层序
auto [a, b] = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
int x = a + dx[k];
int y = b + dy[k];
if (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == '1' &&
vis[x][y] == false) {
q.push({x, y});
vis[x][y] = true;
}
}
}
}
};
三、岛屿的最大面积
题目解析

这道题和求岛屿数量可以说是大同小异,这道题要求我们求出岛屿的最大面积。
算法思路
这道题的结题思路也是和求岛屿数量大同小异;
还是遍历grid数组,在遍历到陆地并且该陆地没有和其他陆地组成岛屿。(遍历到1并且该位置没有被遍历过)
就从该位置进行一次BFS遍历(DFS也可以解决),并求出岛屿的面积;
然后统计岛屿面积的最大值然后返回即可。
代码实现
cpp
class Solution {
public:
typedef pair<int, int> PII;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int vis[55][55] = {false};
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
int ret = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1 && vis[i][j] == false) {
int tmp = bfs(grid, i, j);
ret = max(ret, tmp);
}
}
}
return ret;
}
int bfs(vector<vector<int>>& grid, int i, int j) {
int n = grid.size();
int m = grid[0].size();
queue<PII> q;
q.push({i, j});
vis[i][j] = true;
int ret = 1;
while (q.size()) {
auto [a, b] = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
int x = a + dx[k];
int y = b + dy[k];
if (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == 1 &&
vis[x][y] == false) {
q.push({x, y});
vis[x][y] = true;
ret++;
}
}
}
return ret;
}
};
四、被围绕的区域
题目解析

这道题给定一个字符矩阵board,其中只包含X和O。
题目要求捕获所有被围绕的区域:一块相邻且都是O的区域,如果它不在边缘,就全部修改成X。
算法思路
简单来说,这道题就是让我们将一块相邻且都是O,并且不在边缘的区域全部修改成X。
这里如果直接去解决这个问题,还是有一点难度的(有进行BFS遍历时,还要判断它是否在边缘,不在边缘才能修改)。
直接去修改不行,那我们是不是可以先将在边缘的
O区域进行标记(特殊处理);然后再将没有标记的所有
O都修改成X。最后,复原位于边缘的
O区域。
这里可以创建一个等大的二维数组,来标记是否位于边缘;也可以先将位于边缘的O区域修改成不相干的字符,最后再复原即可。
代码实现
cpp
class Solution {
public:
typedef pair<int, int> PII;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
// bfs
void bfs(vector<vector<char>>& board, vector<vector<bool>>& vis, int i,
int j) {
vis[i][j] = true;
int n = board.size();
int m = board[0].size();
queue<PII> q;
q.push({i, j});
while (q.size() > 0) {
auto [a, b] = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
int x = a + dx[k];
int y = b + dy[k];
if (x >= 0 && x < n && y >= 0 && y < m && board[x][y] == 'O' &&
vis[x][y] == false) {
q.push({x, y});
vis[x][y] = true;
}
}
}
}
void solve(vector<vector<char>>& board) {
// 遍历四周的'o'
int n = board.size();
int m = board[0].size();
vector<vector<bool>> vis(n, vector<bool>(m, false));
for (int i = 0; i < m; i++) {
if (board[0][i] == 'O' && vis[0][i] == false)
bfs(board, vis, 0, i);
if (board[n - 1][i] == 'O' && vis[n - 1][i] == false)
bfs(board, vis, n - 1, i);
}
for (int i = 0; i < n; i++) {
if (board[i][0] == 'O' && vis[i][0] == false)
bfs(board, vis, i, 0);
if (board[i][m - 1] == 'O' && vis[i][m - 1] == false)
bfs(board, vis, i, m - 1);
}
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < m - 1; j++) {
if (board[i][j] == 'O' && vis[i][j] == false)
board[i][j] = 'X';
}
}
}
};
本篇文章到这里就结束了,感谢支持
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws