洪水填充(Flood Fill)是一种基于深度优先搜索(DFS)或广度优先搜索(BFS)的算法,常用于解决图像处理、连通区域标记等问题。其核心思想是从起始点出发,递归或迭代地遍历所有符合条件的相邻区域。
算法实现步骤
定义方向数组
int dx[] = {-1, 1, 0, 0}; // 上下左右
int dy[] = {0, 0, -1, 1};
DFS递归实现
void dfs(vector<vector<int>>& grid, int x, int y, int oldColor, int newColor) {
if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] != oldColor) {
return;
}
grid[x][y] = newColor;
for (int i = 0; i < 4; ++i) {
dfs(grid, x + dx[i], y + dy[i], oldColor, newColor);
}
}
边界条件处理
确保递归或迭代过程中不越界,通常需要检查坐标是否在矩阵范围内。对于连通性问题,还需判断当前点是否符合填充条件(如颜色、数值等)。
性能优化
栈溢出预防 对于大规模矩阵,递归可能导致栈溢出。可改用BFS或显式栈实现的DFS:
void dfs_stack(vector<vector<int>>& grid, int x, int y, int oldColor, int newColor) {
stack<pair<int, int>> st;
st.push({x, y});
while (!st.empty()) {
auto [cx, cy] = st.top();
st.pop();
if (cx < 0 || cx >= grid.size() || cy < 0 || cy >= grid[0].size() || grid[cx][cy] != oldColor) {
continue;
}
grid[cx][cy] = newColor;
for (int i = 0; i < 4; ++i) {
st.push({cx + dx[i], cy + dy[i]});
}
}
}
典型例题
岛屿数量问题
int numIslands(vector<vector<char>>& grid) {
int count = 0;
for (int i = 0; i < grid.size(); ++i) {
for (int j = 0; j < grid[0].size(); ++j) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
++count;
}
}
}
return count;
}
void dfs(vector<vector<char>>& grid, int x, int y) {
if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] != '1') {
return;
}
grid[x][y] = '0';
dfs(grid, x + 1, y);
dfs(grid, x - 1, y);
dfs(grid, x, y + 1);
dfs(grid, x, y - 1);
}
注意事项
- 对于大规模数据,优先使用非递归实现。
- 若需记录访问状态,可额外使用
visited数组避免重复访问。 - 方向数组可根据问题扩展为8方向(加入对角线)。
DFS洪水填充算法详解
499

被折叠的 条评论
为什么被折叠?



