Flood Fill
Recolor a connected region in a grid — DFS or BFS from the start cell.
3 min read
backtracking grid dfs
Problem#
Starting from (sr, sc), replace the color of every 4-connected cell of the same starting color with newColor.
Examples#
image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, newColor = 2→[[2,2,2],[2,2,0],[2,0,1]]
Constraints#
1 <= m, n <= 50.
Approach#
DFS, skipping if already recolored or different color.
Solution#
class Solution {public: vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) { int orig = image[sr][sc]; if (orig == color) return image; function<void(int,int)> dfs = [&](int r, int c) { if (r < 0 || r >= (int)image.size() || c < 0 || c >= (int)image[0].size() || image[r][c] != orig) return; image[r][c] = color; dfs(r+1,c); dfs(r-1,c); dfs(r,c+1); dfs(r,c-1); }; dfs(sr, sc); return image; }};func floodFill(image [][]int, sr int, sc int, color int) [][]int { orig := image[sr][sc] if orig == color { return image } m, n := len(image), len(image[0]) var dfs func(r, c int) dfs = func(r, c int) { if r < 0 || r >= m || c < 0 || c >= n || image[r][c] != orig { return } image[r][c] = color dfs(r+1, c) dfs(r-1, c) dfs(r, c+1) dfs(r, c-1) } dfs(sr, sc) return image}from typing import List
class Solution: def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]: orig = image[sr][sc] if orig == color: return image m, n = len(image), len(image[0])
def dfs(r: int, c: int) -> None: if r < 0 or r >= m or c < 0 or c >= n or image[r][c] != orig: return image[r][c] = color dfs(r + 1, c) dfs(r - 1, c) dfs(r, c + 1) dfs(r, c - 1)
dfs(sr, sc) return imagevar floodFill = function(image, sr, sc, color) { const orig = image[sr][sc]; if (orig === color) return image; const m = image.length, n = image[0].length; const dfs = (r, c) => { if (r < 0 || r >= m || c < 0 || c >= n || image[r][c] !== orig) return; image[r][c] = color; dfs(r + 1, c); dfs(r - 1, c); dfs(r, c + 1); dfs(r, c - 1); }; dfs(sr, sc); return image;};class Solution { private int m, n, orig, color; private int[][] image;
public int[][] floodFill(int[][] image, int sr, int sc, int color) { this.orig = image[sr][sc]; if (orig == color) return image; this.image = image; this.color = color; this.m = image.length; this.n = image[0].length; dfs(sr, sc); return image; }
private void dfs(int r, int c) { if (r < 0 || r >= m || c < 0 || c >= n || image[r][c] != orig) return; image[r][c] = color; dfs(r + 1, c); dfs(r - 1, c); dfs(r, c + 1); dfs(r, c - 1); }}function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] { const orig = image[sr][sc]; if (orig === color) return image; const m = image.length, n = image[0].length; const dfs = (r: number, c: number): void => { if (r < 0 || r >= m || c < 0 || c >= n || image[r][c] !== orig) return; image[r][c] = color; dfs(r + 1, c); dfs(r - 1, c); dfs(r, c + 1); dfs(r, c - 1); }; dfs(sr, sc); return image;}Editorial#
The orig == color guard prevents infinite recursion when no work is needed. Recoloring the visited cell serves dual duty: marks visited and produces the output.
Complexity#
- Time: O(m * n).
- Space: O(m * n) recursion worst case.
Concept revision#
Related#