Browse curriculum

Flood Fill

Implement the 'Paint Bucket' tool found in image editors.

Examples

Input:image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2
Output:[[2,2,2],[2,2,0],[2,0,1]]
Explain:

Start at pixel (1,1). All connected '1's become '2'.

Problem Understanding

You are given an m x n integer grid image representing a bitmap image. You are also given a starting pixel (sr, sc) and a color.

You need to perform a Flood Fill: change the color of the starting pixel and all 4-directionally connected pixels of the same color to color.

Think of the 'Bucket Fill' tool in Paint.

Algorithm Strategy

This is a standard DFS traversal on a grid.

  1. Check Color: Remember original = image[sr][sc]. If it already equals color, return the image — painting would change nothing and the recursion would never stop.
  2. DFS Function: dfs(r, c)
    • Check Bounds: If (r, c) is outside the image, return.
    • Check Match: If image[r][c] != original, return. This also stops at pixels already painted.
    • Paint: Set image[r][c] = color.
    • Recurse: Call dfs down, up, right, then left.

Visualization

Paint from the start pixel. Every call is its own step, in the order the code makes them — down, up, right, left — with an arrow to the pixel about to be tried. A call that leaves the image lands on an empty cell outside it, and a call on a different colour, or on a pixel already painted, returns straight away.

Dry Run

Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2. So original = 1.

Step Call Pixel Action
1 dfs(1,1) 1 Paint 2. Call down.
2 dfs(2,1) 0 Not 1 — return. Back in (1,1): call up.
3 dfs(0,1) 1 Paint 2. Down (1,1) is already 2 and up (-1,1) is outside — both return. Call right.
4 dfs(0,2) 1 Paint 2. Down (1,2) is 0, up and right are outside, left (0,1) is already 2 — all return. Back in (0,1): call left.
5 dfs(0,0) 1 Paint 2. Call down.
6 dfs(1,0) 1 Paint 2. Call down.
7 dfs(2,0) 1 Paint 2. Down is outside, up (1,0) is already 2, right (2,1) is 0, left is outside — all return.
8 back in dfs(1,0) — Up (0,0) and right (1,1) are already 2, left is outside — return.
9 back in dfs(0,0) — Up and left are outside, right (0,1) is already 2 — return. dfs(0,1) is done too.
10 back in dfs(1,1) — Right (1,2) is 0, left (1,0) is already 2 — return.

Result: [[2,2,2],[2,2,0],[2,0,1]]. The bottom-right 1 is never reached: it touches the region only diagonally.

Edge Cases & Common Mistakes

  • Same Color: If color == original, painting changes nothing, so without the early return the recursion would never stop. Check this before the first call.
  • Out of Bounds: Check r and c before reading image[r][c].
  • Diagonals: Only the four side neighbours count. A pixel of the same colour touching only at a corner is not filled.
  • Deep Recursion: A 50 by 50 image of one colour can recurse 2,500 calls deep. That is fine on LeetCode; for larger images use an explicit stack.

Solution

Recursive DFS. The four calls run down, up, right, then left — the order the figure and the dry run follow.

Flood Fill Code
1var floodFill = function(image, sr, sc, color) {
2 const original = image[sr][sc];
3 if (original === color) {
4 return image;
5 }
6 const rows = image.length, cols = image[0].length;
7
8 function dfs(r, c) {
9 if (r < 0 || r >= rows || c < 0 || c >= cols) {
10 return;
11 }
12 if (image[r][c] !== original) {
13 return;
14 }
15 image[r][c] = color;
16 dfs(r + 1, c);
17 dfs(r - 1, c);
18 dfs(r, c + 1);
19 dfs(r, c - 1);
20 }
21
22 dfs(sr, sc);
23 return image;
24};

The approach, step by step

  1. Check the colour

    If image[sr][sc] already equals color, return the image unchanged.

  2. Stop at the edges

    In dfs, return when the pixel is outside the image or is not the original colour.

  3. Paint and spread

    Paint the pixel, then call dfs down, up, right and left.

Frequently asked questions

Why return early when the new colour equals the original?

Painting would not change any pixel, so the check that stops DFS at non-matching pixels would never fire, and the calls would bounce between neighbours forever.


Does the order of the four calls matter?

Not for the result: every connected pixel of the original colour gets painted whatever the order. The order only changes which pixels are painted first.


Can flood fill be done without recursion?

Yes. Push the start pixel onto a stack or queue, and pop pixels, painting each one and pushing its matching neighbours. It does the same work without risking a deep call stack.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description