Given a 2D grid img[][] representing an image, where each element img[i][j] is an integer that denotes the color of a pixel. Also there is a coordinates (sr, sc) representing the starting pixel (row sr and column sc) and an integer newColor, which represents the new color to apply.
We need to perform a flood fill on the image starting from (sr, sc).
It means we must change the color of the starting pixel and all other pixels that are connected to it (directly or indirectly) and have the same original color as the starting pixel.
Two pixels are considered connected if they are adjacent horizontally or vertically (not diagonally).
Example:
Input: sr = 1, sc = 2, newColor = 2, img[][]= [[1, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 1]]
Output: [[2, 2, 2, 0],
[0, 2, 2, 2],
[1, 0, 2,2]]
Explanation: Starting from pixel (1, 2) with value 1, flood fill updates all connected pixels (up, down, left, right) with value 1 to 2. The pixel at (2, 0) remains unchanged because it has no adjacent 1 connected to the starting pixel.
Input: sr = 0, sc = 1, newColor = 0, img[][] = [[0, 1, 0],
[0, 1, 0]]
Output: [[0, 0, 0],
[0, 0, 0]]
Explanation: Starting from pixel (0, 1) which has value 1, flood fill updates all connected pixels (up, down, left, right) with value 1 to 0.
[Approach 1] Using Depth-First Search - O(m * n) Time and O(m * n) Auxiliary Space
The idea is to use Depth-First Search (DFS) because DFS explores all connected cells deeply before backtracking. we need to change the color of the starting pixel and all other pixels that are connected to it having the same original color.
So, we can think of it like this:
We start from the given pixel (sr, sc) and store its color as oldColor. Then, we begin a DFS from that cell. For each cell, we check all its four neighboring cells, If the neighbor is inside the grid and has the same color as oldColor, then that means this pixel should also be filled with the new color. We update it with newColor and recursively call DFS for that neighbor to continue spreading the new color further. If a neighbor has a different color or is outside the grid, we simply return without going deeper. Once all connected cells are visited, we’ll have our final filled image.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
void dfs(vector<vector<int>>& img, int x,
int y, int oldColor, int newColor) {
if (x < 0 || x >= img.size() ||
y < 0 || y >= img[0].size() || img[x][y] != oldColor) {
return;
}
// Update the color of the current pixel
img[x][y] = newColor;
// Recursively visit all 4 connected neighbors
dfs(img, x + 1, y, oldColor, newColor);
dfs(img, x - 1, y, oldColor, newColor);
dfs(img, x, y + 1, oldColor, newColor);
dfs(img, x, y - 1, oldColor, newColor);
}
vector<vector<int>> floodFill(vector<vector<int>>& img, int sr,
int sc, int newColor) {
// If the starting pixel already has the new color,
// no changes are needed
if (img[sr][sc] == newColor) {
return img;
}
// Call DFS to start filling from the source pixel
// Store original color
int oldColor = img[sr][sc];
dfs(img, sr, sc, oldColor, newColor);
return img;
}
//Driver Code Starts
int main() {
vector<vector<int>> img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
vector<vector<int>> result = floodFill(img, sr, sc, newColor);
for (auto& row : result) {
for (auto& pixel : row) {
cout << pixel << " ";
}
cout << "
";
}
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
class GFG {
//Driver Code Ends
static void dfs(int[][] img, int x, int y, int oldColor, int newColor) {
if (x < 0 || x >= img.length ||
y < 0 || y >= img[0].length ||
img[x][y] != oldColor) {
return;
}
// Update the color of the current pixel
img[x][y] = newColor;
// Recursively visit all 4 connected neighbors
dfs(img, x + 1, y, oldColor, newColor);
dfs(img, x - 1, y, oldColor, newColor);
dfs(img, x, y + 1, oldColor, newColor);
dfs(img, x, y - 1, oldColor, newColor);
}
static int[][] floodFill(int[][] img, int sr, int sc, int newColor) {
// If the starting pixel already has the new color,
// no changes are needed
if (img[sr][sc] == newColor) {
return img;
}
// Call DFS to start filling from the source pixel
// Store original color
int oldColor = img[sr][sc];
dfs(img, sr, sc, oldColor, newColor);
return img;
}
//Driver Code Starts
public static void main(String[] args) {
int[][] img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
int[][] result = floodFill(img, sr, sc, newColor);
for (int[] row : result) {
for (int pixel : row) {
System.out.print(pixel + " ");
}
System.out.println();
}
}
}
//Driver Code Ends
Python
def dfs(img, x, y, oldColor, newColor):
if (x < 0 or x >= len(img) or
y < 0 or y >= len(img[0]) or
img[x][y] != oldColor):
return
# Update the color of the current pixel
img[x][y] = newColor
# Recursively visit all 4 connected neighbors
dfs(img, x + 1, y, oldColor, newColor)
dfs(img, x - 1, y, oldColor, newColor)
dfs(img, x, y + 1, oldColor, newColor)
dfs(img, x, y - 1, oldColor, newColor)
def floodFill(img, sr, sc, newColor):
# If the starting pixel already has the new color,
# no changes are needed
if img[sr][sc] == newColor:
return img
# Call DFS to start filling from the source pixel
# Store original color
oldColor = img[sr][sc]
dfs(img, sr, sc, oldColor, newColor)
return img
#Driver Code Starts
if __name__ == "__main__":
img = [
[1, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 1]
]
sr, sc = 1, 2
newColor = 2
result = floodFill(img, sr, sc, newColor)
for row in result:
print(*row)
#Driver Code Ends
C#
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static void dfs(int[,] img, int x, int y, int oldColor, int newColor) {
if (x < 0 || x >= img.GetLength(0) ||
y < 0 || y >= img.GetLength(1) ||
img[x, y] != oldColor) {
return;
}
// Update the color of the current pixel
img[x, y] = newColor;
// Recursively visit all 4 connected neighbors
dfs(img, x + 1, y, oldColor, newColor);
dfs(img, x - 1, y, oldColor, newColor);
dfs(img, x, y + 1, oldColor, newColor);
dfs(img, x, y - 1, oldColor, newColor);
}
static int[,] floodFill(int[,] img, int sr, int sc, int newColor) {
// If the starting pixel already has the new color,
// no changes are needed
if (img[sr, sc] == newColor) {
return img;
}
// Call DFS to start filling from the source pixel
// Store original color
int oldColor = img[sr, sc];
dfs(img, sr, sc, oldColor, newColor);
return img;
}
//Driver Code Starts
static void Main() {
int[,] img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
int[,] result = floodFill(img, sr, sc, newColor);
for (int i = 0; i < result.GetLength(0); i++) {
for (int j = 0; j < result.GetLength(1); j++) {
Console.Write(result[i, j] + " ");
}
Console.WriteLine();
}
}
}
//Driver Code Ends
JavaScript
function dfs(img, x, y, oldColor, newColor) {
if (x < 0 || x >= img.length || y < 0 || y >= img[0].length ||
img[x][y] !== oldColor) {
return;
}
// Update the color of the current pixel
img[x][y] = newColor;
// Recursively visit all 4 connected neighbors
dfs(img, x + 1, y, oldColor, newColor);
dfs(img, x - 1, y, oldColor, newColor);
dfs(img, x, y + 1, oldColor, newColor);
dfs(img, x, y - 1, oldColor, newColor);
}
function floodFill(img, sr, sc, newColor) {
// If the starting pixel already has the new color,
// no changes are needed
if (img[sr][sc] === newColor) {
return img;
}
// Call DFS to start filling from the source pixel
// Store original color
let oldColor = img[sr][sc];
dfs(img, sr, sc, oldColor, newColor);
return img;
}
//Driver Code Starts
//Driver Code
let img = [
[1, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 1]
];
let sr = 1, sc = 2;
let newColor = 2;
let result = floodFill(img, sr, sc, newColor);
for (let row of result) {
console.log(row.join(" "));
}
//Driver Code Ends
Output2 2 2 0
0 2 2 2
1 0 2 2
[Approach 2] Using Breadth-First Search - O(m * n) Time and O(m * n) Space
The idea is the same as DFS, but instead of using recursion, we use Breadth-First Search (BFS) because it avoids recursion overhead.
In BFS, we use a queue and traverse level by level. We start from the given pixel, change its color to the new one, and push it into the queue. Then, for each pixel we pop, we check all four adjacent cells—if any neighbor has the same old color, we update it with the new color and add it to the queue. This continues until all connected pixels are updated.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
//Driver Code Ends
vector<vector<int>> floodFill(vector<vector<int>>& img, int sr,
int sc, int newColor) {
// If the starting pixel already has the new color
if (img[sr][sc] == newColor) {
return img;
}
// Direction vectors for traversing 4 directions
vector<pair<int, int>> dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
queue<pair<int, int>> q;
int oldColor = img[sr][sc];
q.push({sr, sc});
// Change the color of the starting pixel
img[sr][sc] = newColor;
// Perform BFS
while (!q.empty()) {
pair<int, int> front = q.front();
int x = front.first, y = front.second;
q.pop();
// Traverse all 4 directions
for (pair<int, int>& it : dir) {
int nx = x + it.first;
int ny = y + it.second;
// Check boundary conditions and color match
if (nx >= 0 && nx < img.size() &&
ny >= 0 && ny < img[0].size() &&
img[nx][ny] == oldColor) {
img[nx][ny] = newColor;
q.push({nx, ny});
}
}
}
return img;
}
//Driver Code Starts
int main() {
vector<vector<int>> img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
vector<vector<int>> result = floodFill(img, sr, sc, newColor);
for (auto& row : result) {
for (auto& pixel : row) {
cout << pixel << " ";
}
cout << "
";
}
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Queue;
import java.util.LinkedList;
public class GFG {
//Driver Code Ends
public static int[][] floodFill(int[][] img, int sr,
int sc, int newColor) {
// If the starting pixel already has the new color
if (img[sr][sc] == newColor) {
return img;
}
// Direction vectors for traversing 4 directions
int[][] dir = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
Queue<int[]> q = new LinkedList<>();
int oldColor = img[sr][sc];
q.add(new int[]{sr, sc});
// Change the color of the starting pixel
img[sr][sc] = newColor;
// Perform BFS
while (!q.isEmpty()) {
int[] front = q.poll();
int x = front[0], y = front[1];
// Traverse all 4 directions
for (int[] it : dir) {
int nx = x + it[0];
int ny = y + it[1];
// Check boundary conditions and color match
if (nx >= 0 && nx < img.length &&ny >= 0 && ny < img[0].length &&
img[nx][ny] == oldColor) {
img[nx][ny] = newColor;
q.add(new int[]{nx, ny});
}
}
}
return img;
}
//Driver Code Starts
public static void main(String[] args) {
int[][] img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
int[][] result = floodFill(img, sr, sc, newColor);
for (int[] row : result) {
for (int pixel : row) {
System.out.print(pixel + " ");
}
System.out.println();
}
}
}
//Driver Code Ends
Python
#Driver Code Starts
from collections import deque
#Driver Code Ends
def floodFill(img, sr, sc, newColor):
# If the starting pixel already has the new color
if img[sr][sc] == newColor:
return img
# Direction vectors for traversing 4 directions
dir = [(1, 0), (-1, 0), (0, 1), (0, -1)]
q = deque()
oldColor = img[sr][sc]
q.append((sr, sc))
# Change the color of the starting pixel
img[sr][sc] = newColor
# Perform BFS
while q:
x, y = q.popleft()
# Traverse all 4 directions
for dx, dy in dir:
nx = x + dx
ny = y + dy
# Check boundary conditions and color match
if 0 <= nx < len(img) and 0 <= ny < len(img[0]) and img[nx][ny] == oldColor:
img[nx][ny] = newColor
q.append((nx, ny))
return img
#Driver Code Starts
if __name__ == "__main__":
img = [
[1, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 1]
]
sr, sc = 1, 2
newColor = 2
result = floodFill(img, sr, sc, newColor)
for row in result:
print(*row)
#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
class GFG {
//Driver Code Ends
public static int[,] floodFill(int[,] img, int sr,
int sc, int newColor) {
// If the starting pixel already has the new color
if (img[sr, sc] == newColor)
return img;
// Direction vectors for traversing 4 directions
int[,] dir = {
{1, 0}, {-1, 0}, {0, 1}, {0, -1}
};
Queue<(int, int)> q = new Queue<(int, int)>();
int oldColor = img[sr, sc];
q.Enqueue((sr, sc));
// Change the color of the starting pixel
img[sr, sc] = newColor;
int n = img.GetLength(0);
int m = img.GetLength(1);
// Perform BFS
while (q.Count > 0) {
var (x, y) = q.Dequeue();
// Traverse all 4 directions
for (int i = 0; i < 4; i++) {
int nx = x + dir[i, 0];
int ny = y + dir[i, 1];
// Check boundary conditions and color match
if (nx >= 0 && nx < n &&
ny >= 0 && ny < m &&
img[nx, ny] == oldColor) {
img[nx, ny] = newColor;
q.Enqueue((nx, ny));
}
}
}
return img;
}
//Driver Code Starts
static void Main() {
int[,] img = {
{1, 1, 1, 0},
{0, 1, 1, 1},
{1, 0, 1, 1}
};
int sr = 1, sc = 2;
int newColor = 2;
int[,] result = floodFill(img, sr, sc, newColor);
int n = result.GetLength(0);
int m = result.GetLength(1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Console.Write(result[i, j] + " ");
}
Console.WriteLine();
}
}
}
//Driver Code Ends
JavaScript
function floodFill(img, sr, sc, newColor) {
// If the starting pixel already has the new color
if (img[sr][sc] === newColor) return img;
// Direction vectors for traversing 4 directions
const dir = [[1, 0], [-1, 0], [0, 1], [0, -1]];
const q = [];
const oldColor = img[sr][sc];
q.push([sr, sc]);
// Change the color of the starting pixel
img[sr][sc] = newColor;
// Perform BFS
while (q.length > 0) {
const [x, y] = q.shift();
// Traverse all 4 directions
for (const it of dir) {
const nx = x + it[0];
const ny = y + it[1];
// Check boundary conditions and color match
if (nx >= 0 && nx < img.length &&
ny >= 0 && ny < img[0].length &&
img[nx][ny] === oldColor) {
img[nx][ny] = newColor;
q.push([nx, ny]);
}
}
}
return img;
}
//Driver Code
//Driver Code Starts
const img = [
[1, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 1]
];
const sr = 1, sc = 2, newColor = 2;
const result = floodFill(img, sr, sc, newColor);
result.forEach(row => console.log(row.join(" ")));
//Driver Code Ends
Output2 2 2 0
0 2 2 2
1 0 2 2
Flood Fill Algorithm | Computer Graphics
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem