You are given a 2D grid image[][], where each image[i][j] represents the color of a pixel in the image. Also provided is a coordinate(sr, sc) representing the starting pixel (row and column) and a new color value newColor.
Your task is to perform a flood fill starting from the pixel (sr, sc), changing its color and the color of all connected pixels that have the same original color. Two pixels are considered connected if they are adjacent horizontally or vertically (not diagonally) and have the same original color.
Explanation: Starting from pixel (1, 2) with value 1, flood fill updates all connected pixels (up, down, left, right) with value 1 to 2, resulting in [[2, 2, 2, 0], [0, 2, 2, 2], [1, 0, 2, 2]].
Input: image = [[0, 1, 0], [0, 1, 0]], sr = 0, sc = 1, newColor = 0 Output: [[0, 0, 0], [0, 0, 0]] Explanation: Starting from pixel (1, 2) with value 1, flood fill updates all connected pixels (up, down, left, right) with value 1 to 0, resulting in [[0, 0, 0], [0, 0, 0]].
[Approach 1] Using Depth-First Search - O(m * n) Time and O(m * n) Space
The idea is to use Depth-First Search (DFS) to explore and update all connected pixels that share the same original color (color of image[sr][sc]). Starting from the given pixel, DFS recursively checks its adjacent pixels in all four directions—up, down, left, and right. If an adjacent pixel matches the original color, it is updated to the new color, and the DFS continues from that pixel. If not, the algorithm backtracks. This process continues until all connected pixels of the same color are filled with the new color, effectively updating the entire connected component.
Step-by-Step Implementation :
Store the original color at the starting pixel (sr, sc) as this will help in identifying which connected pixels need to be changed..
Define a DFS function that takes the current pixel's row and column as parameters.
In the DFS function, if the current pixel is out of bounds or doesn't match the original color, return (backtrack); otherwise, update its color to newColor and continue the recursion.
Recursively call DFS for all four adjacent directions:
Up: (row - 1, col), Down: (row + 1, col), Left: (row, col - 1), Right: (row, col + 1)
Start DFS from the starting pixel (sr, sc).
Once DFS completes, return the updated image.
C++
#include<iostream>#include<vector>usingnamespacestd;// Helper function for Depth-First Search (DFS)voiddfs(vector<vector<int>>&image,intx,inty,intoldColor,intnewColor){// Base case: check boundary conditions and color mismatchif(x<0||x>=image.size()||y<0||y>=image[0].size()||image[x][y]!=oldColor){// Backtrack if pixel is out of bounds or color doesn't matchreturn;}// Update the color of the current pixelimage[x][y]=newColor;// Recursively visit all 4 connected neighborsdfs(image,x+1,y,oldColor,newColor);dfs(image,x-1,y,oldColor,newColor);dfs(image,x,y+1,oldColor,newColor);dfs(image,x,y-1,oldColor,newColor);}// Main flood fill functionvector<vector<int>>floodFill(vector<vector<int>>&image,intsr,intsc,intnewColor){// If the starting pixel already has the new color,// no changes are neededif(image[sr][sc]==newColor){returnimage;}// Call DFS to start filling from the source pixelintoldColor=image[sr][sc];// Store original colordfs(image,sr,sc,oldColor,newColor);returnimage;// Return the updated image}// Driver code to test the flood fill functionintmain(){// Input image (2D grid)vector<vector<int>>image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// Starting pixel (row, col)intsr=1,sc=2;// New color to applyintnewColor=2;// Perform flood fill and get the resultvector<vector<int>>result=floodFill(image,sr,sc,newColor);// Print the updated imagefor(auto&row:result){for(auto&pixel:row){cout<<pixel<<" ";}cout<<"\n";}return0;}
Java
importjava.util.*;classGfG{// Helper method for DFS traversalstaticvoiddfs(int[][]image,intx,inty,intoldColor,intnewColor){// Base case: check for out-of-bound indices or mismatched colorif(x<0||x>=image.length||y<0||y>=image[0].length||image[x][y]!=oldColor){return;// Backtrack if invalid}// Change the color of the current pixelimage[x][y]=newColor;// Recursively call DFS in all four directionsdfs(image,x+1,y,oldColor,newColor);dfs(image,x-1,y,oldColor,newColor);dfs(image,x,y+1,oldColor,newColor);dfs(image,x,y-1,oldColor,newColor);}// Main function to perform flood fillstaticint[][]floodFill(int[][]image,intsr,intsc,intnewColor){// If the starting pixel already has the new color, no need // to processif(image[sr][sc]==newColor){returnimage;}// Call DFS with the original color of the starting pixeldfs(image,sr,sc,image[sr][sc],newColor);// Return the updated imagereturnimage;}// Driver code to test the flood fill functionpublicstaticvoidmain(String[]args){// Define the image matrixint[][]image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// Starting pixel and the new colorintsr=1,sc=2,newColor=2;// Perform flood fillint[][]result=floodFill(image,sr,sc,newColor);for(int[]row:result){for(intpixel:row){System.out.print(pixel+" ");}System.out.println();}}}
Python
defdfs(image,x,y,oldColor,newColor):# Check boundary conditions and color matchif(x<0orx>=len(image)ory<0ory>=len(image[0])orimage[x][y]!=oldColor):return# Change the colorimage[x][y]=newColor# Visit all adjacent pixelsdfs(image,x+1,y,oldColor,newColor)dfs(image,x-1,y,oldColor,newColor)dfs(image,x,y+1,oldColor,newColor)dfs(image,x,y-1,oldColor,newColor)deffloodFill(image,sr,sc,newColor):# If the starting pixel already has the new colorifimage[sr][sc]==newColor:returnimage# Call DFS with the starting pixel's original colordfs(image,sr,sc,image[sr][sc],newColor)returnimageif__name__=="__main__":# Input initializationimage=[[1,1,1,0],[0,1,1,1],[1,0,1,1]]sr,sc,newColor=1,2,2# Perform flood fillresult=floodFill(image,sr,sc,newColor)forrowinresult:print(" ".join(map(str,row)))
C#
// C# implementation of Flood Fill Algorithm using DFSusingSystem;classGfG{// Helper method to perform DFS and fill connected pixelsstaticvoiddfs(int[,]image,intx,inty,intoldColor,intnewColor){// Base case: check if pixel is out of bounds or not// matching old colorif(x<0||x>=image.GetLength(0)||y<0||y>=image.GetLength(1)||image[x,y]!=oldColor){return;}// Update the current pixel's colorimage[x,y]=newColor;// Recursively call DFS in all 4 directions (up, down, left, right)dfs(image,x+1,y,oldColor,newColor);dfs(image,x-1,y,oldColor,newColor);dfs(image,x,y+1,oldColor,newColor);dfs(image,x,y-1,oldColor,newColor);}// Main function to trigger the flood fillstaticint[,]floodFill(int[,]image,intsr,intsc,intnewColor){// If the pixel at (sr, sc) is already the new color, return as isif(image[sr,sc]==newColor){returnimage;}// Call DFS from the starting pixel using its original colordfs(image,sr,sc,image[sr,sc],newColor);// Return the modified imagereturnimage;}// Driver codestaticvoidMain(string[]args){// Example image (2D grid of pixels)int[,]image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// Starting coordinates (sr, sc) and new color to fillintsr=1,sc=2,newColor=2;// Call flood fill algorithmint[,]result=floodFill(image,sr,sc,newColor);// Print the final filled imagefor(inti=0;i<result.GetLength(0);i++){for(intj=0;j<result.GetLength(1);j++){Console.Write(result[i,j]+" ");}// move to next line after each rowConsole.WriteLine();}}}
JavaScript
functiondfs(image,x,y,oldColor,newColor){// Base case: Check if (x, y) is out of bounds OR pixel// is not of the old colorif(x<0||x>=image.length||y<0||y>=image[0].length||image[x][y]!==oldColor){// Backtrack if invalidreturn;}// Change the color of the current pixel to newColorimage[x][y]=newColor;// Recursively call DFS in all four directionsdfs(image,x+1,y,oldColor,newColor);dfs(image,x-1,y,oldColor,newColor);dfs(image,x,y+1,oldColor,newColor);dfs(image,x,y-1,oldColor,newColor);}// Main function to trigger flood fill using DFSfunctionfloodFill(image,sr,sc,newColor){// Edge case: If the starting pixel already has //the new color, no need to fillif(image[sr][sc]===newColor){returnimage;}// Get the original color of the starting pixelconstoldColor=image[sr][sc];// Start DFS from the given pixeldfs(image,sr,sc,oldColor,newColor);// Return the updated imagereturnimage;}// Sample input image (2D grid of pixels)constimage=[[1,1,1,0],[0,1,1,1],[1,0,1,1]];// Starting coordinates (sr, sc) and the color to fill withconstsr=1,sc=2,newColor=2;// Perform flood fillconstresult=floodFill(image,sr,sc,newColor);// Print the resultresult.forEach(row=>{// Print each row as a space-separated stringconsole.log(row.join(" "));});
Output
2 2 2 0
0 2 2 2
1 0 2 2
Time Complexity: O(m * n), where m and n are the dimensions of the image, as each pixel is visited once. Space Complexity: O(m * n), due to the recursion stack in the worst case of all pixels being connected.
[Approach 2] Using Breadth-First Search - O(m * n) Time and O(m * n) Space
The idea is to use Breadth-First Search (BFS) to change all connected pixels with the original color (color of image[sr][sc]) to a new color (newColor). BFS uses a queue to explore all reachable pixels level by level (horizontally and vertically). For each pixel, it checks its adjacent pixels, and if they match the original color, it changes their color and adds them to the queue for further exploration. This process ensures that all connected pixels are filled with the new color.
The BFS approach would work better in general as it does not require overhead of recursion.
Step-by-Step Implementation :
Save the color of the starting pixel image[sr][sc] in a variable. This helps us identify which pixels need to be changed.
Use a queue (FIFO) to keep track of pixels that need to be processed. Start by adding the starting pixel (sr, sc) to the queue.
Start BFS traversl, While the queue is not empty, remove the front pixel, update its color to newColor, and check all four adjacent pixels, if they're within bounds and match the original color, add them to the queue for further processing.
Repeat until the queue is empty, Continue the above process until all connected pixels with the original color have been visited and updated.
After the BFS traversal, return the updated image with the filled region.
C++
#include<iostream>#include<vector>#include<queue>usingnamespacestd;vector<vector<int>>floodFill(vector<vector<int>>&image,intsr,intsc,intnewColor){// If the starting pixel already has the new colorif(image[sr][sc]==newColor){returnimage;}// Direction vectors for traversing 4 directionsvector<pair<int,int>>directions={{1,0},{-1,0},{0,1},{0,-1}};// Initialize the queue for BFSqueue<pair<int,int>>q;intoldColor=image[sr][sc];q.push({sr,sc});// Change the color of the starting pixelimage[sr][sc]=newColor;// Perform BFSwhile(!q.empty()){pair<int,int>front=q.front();intx=front.first,y=front.second;q.pop();// Traverse all 4 directionsfor(constpair<int,int>&direction:directions){intnx=x+direction.first;intny=y+direction.second;// Check boundary conditions and color matchif(nx>=0&&nx<image.size()&&ny>=0&&ny<image[0].size()&&image[nx][ny]==oldColor){// Change the color and enqueueimage[nx][ny]=newColor;q.push({nx,ny});}}}returnimage;}intmain(){// Define the input 2D image (grid of pixel colors)vector<vector<int>>image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// Starting pixel coordinates (row = 1, column = 2)intsr=1,sc=2;// New color to apply to the connected regionintnewColor=2;// Call the floodFill function to perform DFS/BFS fill from the// starting pixelvector<vector<int>>result=floodFill(image,sr,sc,newColor);// Print the updated image after flood fillfor(auto&row:result){for(auto&pixel:row){// Print each pixel with a spacecout<<pixel<<" ";}// Move to the next line after printing each rowcout<<"\n";}return0;}
Java
// Java implementation of Flood Fill Algorithm// using BFSimportjava.util.*;classGfG{// Directions for traversing in 4-neighbor cellsprivatestaticfinalint[][]directions={{1,0},{-1,0},{0,1},{0,-1}};publicstaticint[][]floodFill(int[][]image,intsr,intsc,intnewColor){// If the starting pixel already has the new colorif(image[sr][sc]==newColor){returnimage;}intoldColor=image[sr][sc];Queue<int[]>q=newLinkedList<>();q.offer(newint[]{sr,sc});// Change the color of the starting pixelimage[sr][sc]=newColor;while(!q.isEmpty()){int[]front=q.poll();intx=front[0],y=front[1];for(int[]direction:directions){intnx=x+direction[0];intny=y+direction[1];// Check boundary conditions and color matchif(nx>=0&&nx<image.length&&ny>=0&&ny<image[0].length&&image[nx][ny]==oldColor){// Change the color and enqueueimage[nx][ny]=newColor;q.offer(newint[]{nx,ny});}}}returnimage;}publicstaticvoidmain(String[]args){// Define the input 2D image as a matrix where // each element represents a pixel's colorint[][]image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// sr: starting row index, sc: starting column // index for the flood fillintsr=1,sc=2;// newColor: the color that we want to fill the // connected component withintnewColor=2;// Call the floodFill function to apply the // newColor starting from (sr, sc)int[][]result=floodFill(image,sr,sc,newColor);// Print the updated image after flood fillfor(int[]row:result){for(intpixel:row){System.out.print(pixel+" ");}// Move to the next line after each rowSystem.out.println();}}}
Python
fromcollectionsimportdeque# Function to perform flood fill using BFSdeffloodFill(image,sr,sc,newColor):rows,cols=len(image),len(image[0])# Store the color at the starting pixeloldColor=image[sr][sc]# Return the image if the starting pixel # already has the new colorifoldColor==newColor:returnimage# Create a queue to manage the BFS traversalq=deque([(sr,sc)])# Directions to explore: down, up, right, leftdirections=[(1,0),(-1,0),(0,1),(0,-1)]# Change the color of the starting pixelimage[sr][sc]=newColor# BFS traversalwhileq:x,y=q.popleft()# Explore all four possible directionsfordx,dyindirections:nx,ny=x+dx,y+dy# Check if new coordinates are within bounds # and have the old colorif0<=nx<rowsand0<=ny<cols \
andimage[nx][ny]==oldColor:# Change the color and add the pixel to # queue for further explorationimage[nx][ny]=newColorq.append((nx,ny))returnimageif__name__=="__main__":# Input 2D image represented as a grid of pixels # (each with an integer color)image=[[1,1,1,0],[0,1,1,1],[1,0,1,1]]# Starting pixel coordinates (sr, sc) and the new color to applysr,sc,newColor=1,2,2# Perform the flood fill operationresult=floodFill(image,sr,sc,newColor)# Print the updated image row by rowforrowinresult:# Convert each row's integers to strings and join them with spacesprint(" ".join(map(str,row)))
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// BFS-based Flood Fill implementationstaticint[,]floodFill(int[,]image,intsr,intsc,intnewColor){// Get the original color of the starting pixelintoldColor=image[sr,sc];// If the starting pixel already has the new // color, return the imageif(oldColor==newColor){returnimage;}// Dimensions of the imageintrows=image.GetLength(0);intcols=image.GetLength(1);// Queue for BFSQueue<(int,int)>q=newQueue<(int,int)>();// Add the starting pixel to the queueq.Enqueue((sr,sc));// Change the starting pixel colorimage[sr,sc]=newColor;// Direction vectors for adjacent pixelsint[]dx={-1,1,0,0};int[]dy={0,0,-1,1};// BFS loopwhile(q.Count>0){(intx,inty)=q.Dequeue();// Traverse all 4 directionsfor(inti=0;i<4;i++){intnx=x+dx[i];intny=y+dy[i];// Check boundary conditions and color matchif(nx>=0&&nx<rows&&ny>=0&&ny<cols&&image[nx,ny]==oldColor){// Change the colorimage[nx,ny]=newColor;// Add the pixel to the queueq.Enqueue((nx,ny));}}}returnimage;}staticvoidMain(string[]args){// Define a 2D array (matrix) representing the image where // each element is a pixel colorint[,]image={{1,1,1,0},{0,1,1,1},{1,0,1,1}};// sr: starting row, sc: starting column, newColor: the color to applyintsr=1,sc=2,newColor=2;// Call the floodFill function to apply the new color to // connected pixelsint[,]result=floodFill(image,sr,sc,newColor);// Print the updated imagefor(inti=0;i<result.GetLength(0);i++){for(intj=0;j<result.GetLength(1);j++){Console.Write(result[i,j]+" ");}Console.WriteLine();}}}
JavaScript
functionfloodFill(image,sr,sc,newColor){constoldColor=image[sr][sc];// If the starting pixel already has the new color, returnif(oldColor===newColor){returnimage;}// Dimensions of the imageconstrows=image.length;constcols=image[0].length;// Queue for BFSconstq=[[sr,sc]];// Change the starting pixel's colorimage[sr][sc]=newColor;// Direction vectors for 4 adjacent directionsconstdirections=[[1,0],[-1,0],[0,1],[0,-1]];// BFS loopwhile(q.length>0){const[x,y]=q.shift();for(const[dx,dy]ofdirections){constnx=x+dx;constny=y+dy;// Check boundary conditions and color matchif(nx>=0&&nx<rows&&ny>=0&&ny<cols&&image[nx][ny]===oldColor){// Change color and add to queueimage[nx][ny]=newColor;q.push([nx,ny]);}}}returnimage;}// Define a 2D array (image) where each element represents a pixel's colorconstimage=[[1,1,1,0],[0,1,1,1],[1,0,1,1]];// sr: starting row, sc: starting column, newColor: the color to fillconstsr=1,sc=2,newColor=2;// Call the floodFill function to update the image with the new colorconstresult=floodFill(image,sr,sc,newColor);// Print the updated image row by rowresult.forEach(row=>{// Join each row's elements with a space and print the rowconsole.log(row.join(" "));});
Output
2 2 2 0
0 2 2 2
1 0 2 2
Time Complexity: O(m * n),as all pixels are visited once in bfs. Space Complexity: O(m * n), because the queue can hold all pixels in the worst-case scenario.
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.