GeeksforGeeks App
Open App
Browser
Continue

# Flood Fill Algorithm

Given a 2D screen arr[][] where each arr[i][j] is an integer representing the color of that pixel, also given the location of a pixel (X, Y) and a color C, the task is to replace the color of the given pixel and all the adjacent same-colored pixels with the given color.

Example:

Input: arr[][] = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 0},
{1, 0, 0, 1, 1, 0, 1, 1},
{1, 2, 2, 2, 2, 0, 1, 0},
{1, 1, 1, 2, 2, 0, 1, 0},
{1, 1, 1, 2, 2, 2, 2, 0},
{1, 1, 1, 1, 1, 2, 1, 1},
{1, 1, 1, 1, 1, 2, 2, 1}}
X = 4, Y = 4, C = 3
Output:
1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0
1 0 0 1 1 0 1 1
1 3 3 3 3 0 1 0
1 1 1 3 3 0 1 0
1 1 1 3 3 3 3
1 1 1 1 1 3 1 1
1 1 1 1 1 3 3
Explanation:
The values in the given 2D screen indicate colors of the pixels. X and Y are coordinates of the brush, C is the color that should replace the previous color on screen[X][Y] and all surrounding pixels with the same color. Hence all the 2 are replaced with 3.

BFS Approach: The idea is to use BFS traversal to replace the color with the new color.

• Create an empty queue lets say Q.
• Push the starting location of the pixel as given in the input and apply replacement color to it.
• Iterate until Q is not empty and pop the front node (pixel position).
• Check the pixels adjacent to the current pixel and push into the queue if valid (had not been colored with replacement color and have the same color as the old color).

Below is the implementation of the above approach:

## C++

 // C++ implementation of the approach#include using namespace std; // Function that returns true if// the given pixel is validbool isValid(int screen[][8], int m, int n, int x, int y, int prevC, int newC){    if(x < 0 || x >= m || y < 0 || y >= n || screen[x][y] != prevC       || screen[x][y]== newC)        return false;    return true;}  // FloodFill functionvoid floodFill(int screen[][8], int m, int n, int x, int y, int prevC, int newC){    vector> queue;     // Append the position of starting    // pixel of the component    pair p(x,y);    queue.push_back(p);     // Color the pixel with the new color    screen[x][y] = newC;     // While the queue is not empty i.e. the    // whole component having prevC color    // is not colored with newC color    while(queue.size() > 0)    {        // Dequeue the front node        pair currPixel = queue[queue.size() - 1];        queue.pop_back();         int posX = currPixel.first;        int posY = currPixel.second;         // Check if the adjacent        // pixels are valid        if(isValid(screen, m, n, posX + 1, posY, prevC, newC))        {            // Color with newC            // if valid and enqueue            screen[posX + 1][posY] = newC;            p.first = posX + 1;            p.second = posY;            queue.push_back(p);        }         if(isValid(screen, m, n, posX-1, posY, prevC, newC))        {            screen[posX-1][posY]= newC;            p.first = posX-1;            p.second = posY;            queue.push_back(p);        }         if(isValid(screen, m, n, posX, posY + 1, prevC, newC))        {            screen[posX][posY + 1]= newC;            p.first = posX;            p.second = posY + 1;            queue.push_back(p);        }         if(isValid(screen, m, n, posX, posY-1, prevC, newC))        {            screen[posX][posY-1]= newC;            p.first = posX;            p.second = posY-1;            queue.push_back(p);        }    }}     int main(){    int screen[][8] ={    {1, 1, 1, 1, 1, 1, 1, 1},    {1, 1, 1, 1, 1, 1, 0, 0},    {1, 0, 0, 1, 1, 0, 1, 1},    {1, 2, 2, 2, 2, 0, 1, 0},    {1, 1, 1, 2, 2, 0, 1, 0},    {1, 1, 1, 2, 2, 2, 2, 0},    {1, 1, 1, 1, 1, 2, 1, 1},    {1, 1, 1, 1, 1, 2, 2, 1}};        // Row of the display    int m = 8;        // Column of the display    int n = 8;        // Co-ordinate provided by the user    int x = 4;    int y = 4;        // Current color at that co-ordinate    int prevC = screen[x][y];        // New color that has to be filled    int newC = 3;    floodFill(screen, m, n, x, y, prevC, newC);        // Printing the updated screen    for(int i = 0; i < m; i++)    {        for(int j = 0; j < n; j++)        {            cout << screen[i][j] << " ";        }        cout << endl;    }     return 0;} // This code is contributed by suresh07.

## Java

 // Java implementation of the approachimport java.util.*;import java.awt.Point;public class Main{    // Function that returns true if    // the given pixel is valid    static boolean isValid(int[][] screen, int m, int n, int x, int y, int prevC, int newC)    {        if(x < 0 || x >= m || y < 0 || y >= n || screen[x][y] != prevC           || screen[x][y]== newC)            return false;        return true;    }          // FloodFill function    static void floodFill(int[][] screen, int m, int n, int x, int y, int prevC, int newC)    {        Vector queue = new Vector();           // Append the position of starting        // pixel of the component        queue.add(new Point(x, y));           // Color the pixel with the new color        screen[x][y] = newC;           // While the queue is not empty i.e. the        // whole component having prevC color        // is not colored with newC color        while(queue.size() > 0)        {            // Dequeue the front node            Point currPixel = queue.get(queue.size() - 1);            queue.remove(queue.size() - 1);               int posX = currPixel.x;            int posY = currPixel.y;               // Check if the adjacent            // pixels are valid            if(isValid(screen, m, n, posX + 1, posY, prevC, newC))            {                // Color with newC                // if valid and enqueue                screen[posX + 1][posY] = newC;                queue.add(new Point(posX + 1, posY));            }               if(isValid(screen, m, n, posX-1, posY, prevC, newC))            {                screen[posX-1][posY]= newC;                queue.add(new Point(posX-1, posY));            }               if(isValid(screen, m, n, posX, posY + 1, prevC, newC))            {                screen[posX][posY + 1]= newC;                queue.add(new Point(posX, posY + 1));            }               if(isValid(screen, m, n, posX, posY-1, prevC, newC))            {                screen[posX][posY-1]= newC;                queue.add(new Point(posX, posY-1));            }        }    }         public static void main(String[] args) {        int[][] screen ={        {1, 1, 1, 1, 1, 1, 1, 1},        {1, 1, 1, 1, 1, 1, 0, 0},        {1, 0, 0, 1, 1, 0, 1, 1},        {1, 2, 2, 2, 2, 0, 1, 0},        {1, 1, 1, 2, 2, 0, 1, 0},        {1, 1, 1, 2, 2, 2, 2, 0},        {1, 1, 1, 1, 1, 2, 1, 1},        {1, 1, 1, 1, 1, 2, 2, 1}};               // Row of the display        int m = screen.length;               // Column of the display        int n = screen.length;               // Co-ordinate provided by the user        int x = 4;        int y = 4;               // Current color at that co-ordinate        int prevC = screen[x][y];               // New color that has to be filled        int newC = 3;        floodFill(screen, m, n, x, y, prevC, newC);               // Printing the updated screen        for(int i = 0; i < m; i++)        {            for(int j = 0; j < n; j++)            {                System.out.print(screen[i][j] + " ");            }            System.out.println();        }    }} // This code is contributed by mukesh07.

## Python3

 # Python3 implementation of the approach # Function that returns true if# the given pixel is validdef isValid(screen, m, n, x, y, prevC, newC):    if x<0 or x>= m\       or y<0 or y>= n or\       screen[x][y]!= prevC\       or screen[x][y]== newC:        return False    return True  # FloodFill functiondef floodFill(screen,             m, n, x,             y, prevC, newC):    queue = []         # Append the position of starting    # pixel of the component    queue.append([x, y])     # Color the pixel with the new color    screen[x][y] = newC     # While the queue is not empty i.e. the    # whole component having prevC color    # is not colored with newC color    while queue:                 # Dequeue the front node        currPixel = queue.pop()                 posX = currPixel[0]        posY = currPixel[1]                 # Check if the adjacent        # pixels are valid        if isValid(screen, m, n,                 posX + 1, posY,                         prevC, newC):                         # Color with newC            # if valid and enqueue            screen[posX + 1][posY] = newC            queue.append([posX + 1, posY])                 if isValid(screen, m, n,                     posX-1, posY,                         prevC, newC):            screen[posX-1][posY]= newC            queue.append([posX-1, posY])                 if isValid(screen, m, n,                 posX, posY + 1,                         prevC, newC):            screen[posX][posY + 1]= newC            queue.append([posX, posY + 1])                 if isValid(screen, m, n,                     posX, posY-1,                         prevC, newC):            screen[posX][posY-1]= newC            queue.append([posX, posY-1])   # Driver codescreen =[[1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 0, 0],[1, 0, 0, 1, 1, 0, 1, 1],[1, 2, 2, 2, 2, 0, 1, 0],[1, 1, 1, 2, 2, 0, 1, 0],[1, 1, 1, 2, 2, 2, 2, 0],[1, 1, 1, 1, 1, 2, 1, 1],[1, 1, 1, 1, 1, 2, 2, 1],    ]     # Row of the displaym = len(screen) # Column of the displayn = len(screen[0]) # Co-ordinate provided by the userx = 4y = 4 # Current color at that co-ordinateprevC = screen[x][y] # New color that has to be fillednewC = 3 floodFill(screen, m, n, x, y, prevC, newC)  # Printing the updated screenfor i in range(m):    for j in range(n):        print(screen[i][j], end =' ')    print()

## C#

 // C# implementation of the approachusing System;using System.Collections.Generic;class GFG {         // Function that returns true if    // the given pixel is valid    static bool isValid(int[,] screen, int m, int n, int x, int y, int prevC, int newC)    {        if(x < 0 || x >= m || y < 0 || y >= n || screen[x, y] != prevC           || screen[x,y]== newC)            return false;        return true;    }        // FloodFill function    static void floodFill(int[,] screen, int m, int n, int x, int y, int prevC, int newC)    {        List> queue = new List>();          // Append the position of starting        // pixel of the component        queue.Add(new Tuple(x, y));          // Color the pixel with the new color        screen[x,y] = newC;          // While the queue is not empty i.e. the        // whole component having prevC color        // is not colored with newC color        while(queue.Count > 0)        {            // Dequeue the front node            Tuple currPixel = queue[queue.Count - 1];            queue.RemoveAt(queue.Count - 1);              int posX = currPixel.Item1;            int posY = currPixel.Item2;              // Check if the adjacent            // pixels are valid            if(isValid(screen, m, n, posX + 1, posY, prevC, newC))            {                // Color with newC                // if valid and enqueue                screen[posX + 1,posY] = newC;                queue.Add(new Tuple(posX + 1, posY));            }              if(isValid(screen, m, n, posX-1, posY, prevC, newC))            {                screen[posX-1,posY]= newC;                queue.Add(new Tuple(posX-1, posY));            }              if(isValid(screen, m, n, posX, posY + 1, prevC, newC))            {                screen[posX,posY + 1]= newC;                queue.Add(new Tuple(posX, posY + 1));            }              if(isValid(screen, m, n, posX, posY-1, prevC, newC))            {                screen[posX,posY-1]= newC;                queue.Add(new Tuple(posX, posY-1));            }        }    }       static void Main() {    int[,] screen ={    {1, 1, 1, 1, 1, 1, 1, 1},    {1, 1, 1, 1, 1, 1, 0, 0},    {1, 0, 0, 1, 1, 0, 1, 1},    {1, 2, 2, 2, 2, 0, 1, 0},    {1, 1, 1, 2, 2, 0, 1, 0},    {1, 1, 1, 2, 2, 2, 2, 0},    {1, 1, 1, 1, 1, 2, 1, 1},    {1, 1, 1, 1, 1, 2, 2, 1}};      // Row of the display    int m = screen.GetLength(0);      // Column of the display    int n = screen.GetLength(1);      // Co-ordinate provided by the user    int x = 4;    int y = 4;      // Current color at that co-ordinate    int prevC = screen[x,y];      // New color that has to be filled    int newC = 3;    floodFill(screen, m, n, x, y, prevC, newC);      // Printing the updated screen    for(int i = 0; i < m; i++)    {        for(int j = 0; j < n; j++)        {            Console.Write(screen[i,j] + " ");        }        Console.WriteLine();    }  }} // This code is contributed by divyeshrabadiya07.

## Javascript



Output

1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0
1 0 0 1 1 0 1 1
1 3 3 3 3 0 1 0
1 1 1 3 3 0 1 0
1 1 1 3 3 3 3 0
1 1 1 1 1 3 1 1
1 1 1 1 1 3 3 1

Time Complexity: O(N*M)
Auxiliary Space: O(N*M)

An Approach using DFS:

• Change the color of source row and source column with given color
• Do dfs in four direction

Below is the implementation of the above approach:

## C++

 // C++ implementation of the approach#include using namespace std; // Floodfill functionvoid floodFill(vector >& screen, int sr, int sc,               int row, int col, int source, int color){    // Condition for checking out of bounds    if (sr < 0 || sr >= row || sc < 0 || sc >= col)        return;     if (screen[sr][sc] != source)        return;       screen[sr][sc] = color;    floodFill(screen, sr - 1, sc, row, col, source,              color); // left    floodFill(screen, sr + 1, sc, row, col, source,              color); // right    floodFill(screen, sr, sc + 1, row, col, source,              color); // top    floodFill(screen, sr, sc - 1, row, col, source,              color); // bottom} // Driver codeint main(){    vector > screen        = { { 1, 1, 1, 1, 1, 1, 1, 1 },            { 1, 1, 1, 1, 1, 1, 0, 0 },            { 1, 0, 0, 1, 1, 0, 1, 1 },            { 1, 2, 2, 2, 2, 0, 1, 0 },            { 1, 1, 1, 2, 2, 0, 1, 0 },            { 1, 1, 1, 2, 2, 2, 2, 0 },            { 1, 1, 1, 1, 1, 2, 1, 1 },            { 1, 1, 1, 1, 1, 2, 2, 1 } };     // Row of the display    int m = 8;     // Column of the display    int n = 8;     // Co-ordinate provided by the user    int x = 4;    int y = 4;     // Current color at that co-ordinate    int prevC = screen[x][y];     // New color that has to be filled    int newC = 3;     floodFill(screen, x, y, m, n, prevC, newC);     // Printing the updated screen    for (int i = 0; i < m; i++) {        for (int j = 0; j < n; j++) {            cout << screen[i][j] << " ";        }        cout << endl;    }     return 0;} // This code is contributed by hkdass001.

## Java

 import java.util.ArrayList; public class FloodFill {// Floodfill functionpublic static void floodFill(int[][] screen, int sr, int sc,int row, int col, int source, int color) {// Condition for checking out of boundsif (sr < 0 || sr >= row || sc < 0 || sc >= col)return;     if (screen[sr][sc] != source)        return;     screen[sr][sc] = color;    floodFill(screen, sr - 1, sc, row, col, source, color); // left    floodFill(screen, sr + 1, sc, row, col, source, color); // right    floodFill(screen, sr, sc + 1, row, col, source, color); // top    floodFill(screen, sr, sc - 1, row, col, source, color); // bottom} public static void main(String[] args) {    int[][] screen = {{1, 1, 1, 1, 1, 1, 1, 1},            {1, 1, 1, 1, 1, 1, 0, 0},            {1, 0, 0, 1, 1, 0, 1, 1},            {1, 2, 2, 2, 2, 0, 1, 0},            {1, 1, 1, 2, 2, 0, 1, 0},            {1, 1, 1, 2, 2, 2, 2, 0},            {1, 1, 1, 1, 1, 2, 1, 1},            {1, 1, 1, 1, 1, 2, 2, 1}};     // Row of the display    int m = 8;     // Column of the display    int n = 8;     // Co-ordinate provided by the user    int x = 4;    int y = 4;     // Current color at that co-ordinate    int prevC = screen[x][y];     // New color that has to be filled    int newC = 3;     floodFill(screen, x, y, m, n, prevC, newC);     // Printing the updated screen    for (int i = 0; i < m; i++) {        for (int j = 0; j < n; j++) {            System.out.print(screen[i][j] + " ");        }        System.out.println();    }} }

## Python3

 from typing import List, Tuple def flood_fill(screen: List[List[int]], sr: int, sc: int, row: int, col: int, source: int, color: int) -> None:    # Condition for checking out of bounds    if sr < 0 or sr >= row or sc < 0 or sc >= col:        return     if screen[sr][sc] != source:        return     screen[sr][sc] = color    flood_fill(screen, sr - 1, sc, row, col, source, color) # left    flood_fill(screen, sr + 1, sc, row, col, source, color) # right    flood_fill(screen, sr, sc + 1, row, col, source, color) # top    flood_fill(screen, sr, sc - 1, row, col, source, color) # bottom if __name__ == "__main__":    screen = [        [1, 1, 1, 1, 1, 1, 1, 1],        [1, 1, 1, 1, 1, 1, 0, 0],        [1, 0, 0, 1, 1, 0, 1, 1],        [1, 2, 2, 2, 2, 0, 1, 0],        [1, 1, 1, 2, 2, 0, 1, 0],        [1, 1, 1, 2, 2, 2, 2, 0],        [1, 1, 1, 1, 1, 2, 1, 1],        [1, 1, 1, 1, 1, 2, 2, 1]    ]     # Row of the display    m = 8     # Column of the display    n = 8     # Coordinate provided by the user    x = 4    y = 4     # Current color at that coordinate    prevC = screen[x][y]     # New color that has to be filled    newC = 3     flood_fill(screen, x, y, m, n, prevC, newC)     # Printing the updated screen    for i in range(m):        for j in range(n):            print(screen[i][j], end=" ")        print()

## Javascript

 // JavaScript implementation of the approach  // Floodfill functionfunction floodFill(screen, sr, sc, row, col, source, color){    // Condition for checking out of bounds    if (sr < 0 || sr >= row || sc < 0 || sc >= col) return;     if (screen[sr][sc] != source) return;     screen[sr][sc] = color;    floodFill(screen, sr - 1, sc, row, col, source, color); // left    floodFill(screen, sr + 1, sc, row, col, source, color); // right    floodFill(screen, sr, sc + 1, row, col, source, color); // top    floodFill(screen, sr, sc - 1, row, col, source, color); // bottom} // Driver codelet screen = [  [ 1, 1, 1, 1, 1, 1, 1, 1 ],                [ 1, 1, 1, 1, 1, 1, 0, 0 ],                [ 1, 0, 0, 1, 1, 0, 1, 1 ],                [ 1, 2, 2, 2, 2, 0, 1, 0 ],                [ 1, 1, 1, 2, 2, 0, 1, 0 ],                [ 1, 1, 1, 2, 2, 2, 2, 0 ],                [ 1, 1, 1, 1, 1, 2, 1, 1 ],                [ 1, 1, 1, 1, 1, 2, 2, 1 ] ];  // Row of the displaylet m = 8; // Column of the displaylet n = 8; // Co-ordinate provided by the userlet x = 4;let y = 4; // Current color at that co-ordinatelet prevC = screen[x][y]; // New color that has to be filledlet newC = 3; floodFill(screen, x, y, m, n, prevC, newC); // Printing the updated screenfor (let i = 0; i < m; i++) {    let temp = "";    for (let j = 0; j < n; j++) {           document.write(screen[i][j] + " ");    }    document.write("
");}  // This code is contributed by Gautam goel

## C#

 using System; namespace FloodFill{    class Program    {        static void Main(string[] args)        {            int[,] screen =            {                {1, 1, 1, 1, 1, 1, 1, 1},                {1, 1, 1, 1, 1, 1, 0, 0},                {1, 0, 0, 1, 1, 0, 1, 1},                {1, 2, 2, 2, 2, 0, 1, 0},                {1, 1, 1, 2, 2, 0, 1, 0},                {1, 1, 1, 2, 2, 2, 2, 0},                {1, 1, 1, 1, 1, 2, 1, 1},                {1, 1, 1, 1, 1, 2, 2, 1}            };             // Dimensions of the screen            int m = 8;            int n = 8;             // Coordinates provided by the user            int x = 4;            int y = 4;             // Current color at the given coordinate            int prevC = screen[x, y];             // New color to fill            int newC = 3;             FloodFill(screen, x, y, m, n, prevC, newC);             // Printing the updated screen            for (int i = 0; i < m; i++)            {                for (int j = 0; j < n; j++)                {                    Console.Write(screen[i, j] + " ");                }                Console.WriteLine();            }             Console.ReadKey();        }         // Flood fill function        static void FloodFill(int[,] screen, int sr, int sc, int row, int col, int source, int color)        {            // Check for out of bounds            if (sr < 0 || sr >= row || sc < 0 || sc >= col)                return;             // Check if the current pixel is not equal to the source color            if (screen[sr, sc] != source)                return;             screen[sr, sc] = color;             // Recursively fill the surrounding pixels            FloodFill(screen, sr - 1, sc, row, col, source, color); // left            FloodFill(screen, sr + 1, sc, row, col, source, color); // right            FloodFill(screen, sr, sc + 1, row, col, source, color); // top            FloodFill(screen, sr, sc - 1, row, col, source, color); // bottom        }    }}

Output

1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0
1 0 0 1 1 0 1 1
1 3 3 3 3 0 1 0
1 1 1 3 3 0 1 0
1 1 1 3 3 3 3 0
1 1 1 1 1 3 1 1
1 1 1 1 1 3 3 1

Time Complexity: O(m*n)
Auxiliary Space: O(m + n), due to the recursive call stack.

My Personal Notes arrow_drop_up