Flood Fill Algorithm

Flood Fill Algorithm

·

2 min read

Flood fill is a process to alter the area in a multi-dimensional array. Take below gif(from wiki) as an example, with flood fill, the middle area is filled with different color.

Recursive_Flood_Fill_4_(aka).gif

This algorithm often used in the bucket fill tool in paint programs or games.

In leetcode Flood Fill problem, the area is an image, the problem is to perform a flood fill from the start pixel to pixels(4-directionally) in same color with a new color.

This problem is pretty simple, we could either use breadth-first approach or depth-first approach.

Let first see the breadth-first approach.

function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
    const oldColor = image[sr][sc];
    if (oldColor === newColor) return image;

    let queue = [[sr, sc]];
    while (true) {
        const pixel = queue.shift();
        if (!pixel) break;

        const [sr, sc] = pixel;
        if (oldColor !== image[sr][sc]) continue;

        image[sr][sc] = newColor;
        if (sr + 1 < image.length) {
            queue.push([sr + 1, sc]);
        }
        if (sc + 1 < image[0].length) {
            queue.push([sr, sc + 1]);
        }
        if (sr - 1 >= 0) {
            queue.push([sr - 1, sc]);
        }
        if (sc - 1 >= 0) {
            queue.push([sr, sc - 1]);
        }
    }

    return image;
};

It is a pretty standard procedure, just use a queue to save the breadth candidates, and fill the cell one by one.

Now let's see the depth-first approach.

function dfs(image: number[][], sr: number, sc: number, oldColor: number, newColor: number) {
    if (image[sr][sc] !== oldColor) return;

    image[sr][sc] = newColor;
    if (sr + 1 < image.length) dfs(image, sr + 1, sc, oldColor, newColor);
    if (sc + 1 < image[0].length) dfs(image, sr, sc + 1, oldColor, newColor);
    if (sr - 1 >= 0) dfs(image, sr - 1, sc, oldColor, newColor);
    if (sc - 1 >= 0) dfs(image, sr, sc - 1, oldColor, newColor);
}

function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
    const oldColor = image[sr][sc];
    if (oldColor !== color) {
        dfs(image, sr, sc, oldColor, color);
    }
    return image;
};