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).
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>usingnamespacestd;//Driver Code Endsvoiddfs(vector<vector<int>>&img,intx,inty,intoldColor,intnewColor){if(x<0||x>=img.size()||y<0||y>=img[0].size()||img[x][y]!=oldColor){return;}// Update the color of the current pixelimg[x][y]=newColor;// Recursively visit all 4 connected neighborsdfs(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,intsr,intsc,intnewColor){// If the starting pixel already has the new color,// no changes are neededif(img[sr][sc]==newColor){returnimg;}// Call DFS to start filling from the source pixel// Store original colorintoldColor=img[sr][sc];dfs(img,sr,sc,oldColor,newColor);returnimg;}//Driver Code Startsintmain(){vector<vector<int>>img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;vector<vector<int>>result=floodFill(img,sr,sc,newColor);for(auto&row:result){for(auto&pixel:row){cout<<pixel<<" ";}cout<<"";}return0;}//Driver Code Ends
Java
//Driver Code StartsclassGFG{//Driver Code Endsstaticvoiddfs(int[][]img,intx,inty,intoldColor,intnewColor){if(x<0||x>=img.length||y<0||y>=img[0].length||img[x][y]!=oldColor){return;}// Update the color of the current pixelimg[x][y]=newColor;// Recursively visit all 4 connected neighborsdfs(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);}staticint[][]floodFill(int[][]img,intsr,intsc,intnewColor){// If the starting pixel already has the new color,// no changes are neededif(img[sr][sc]==newColor){returnimg;}// Call DFS to start filling from the source pixel// Store original colorintoldColor=img[sr][sc];dfs(img,sr,sc,oldColor,newColor);returnimg;}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;int[][]result=floodFill(img,sr,sc,newColor);for(int[]row:result){for(intpixel:row){System.out.print(pixel+" ");}System.out.println();}}}//Driver Code Ends
Python
defdfs(img,x,y,oldColor,newColor):if(x<0orx>=len(img)ory<0ory>=len(img[0])orimg[x][y]!=oldColor):return# Update the color of the current pixelimg[x][y]=newColor# Recursively visit all 4 connected neighborsdfs(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)deffloodFill(img,sr,sc,newColor):# If the starting pixel already has the new color,# no changes are neededifimg[sr][sc]==newColor:returnimg# Call DFS to start filling from the source pixel# Store original coloroldColor=img[sr][sc]dfs(img,sr,sc,oldColor,newColor)returnimg#Driver Code Startsif__name__=="__main__":img=[[1,1,1,0],[0,1,1,1],[1,0,1,1]]sr,sc=1,2newColor=2result=floodFill(img,sr,sc,newColor)forrowinresult:print(*row)#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code Endsstaticvoiddfs(int[,]img,intx,inty,intoldColor,intnewColor){if(x<0||x>=img.GetLength(0)||y<0||y>=img.GetLength(1)||img[x,y]!=oldColor){return;}// Update the color of the current pixelimg[x,y]=newColor;// Recursively visit all 4 connected neighborsdfs(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);}staticint[,]floodFill(int[,]img,intsr,intsc,intnewColor){// If the starting pixel already has the new color,// no changes are neededif(img[sr,sc]==newColor){returnimg;}// Call DFS to start filling from the source pixel// Store original colorintoldColor=img[sr,sc];dfs(img,sr,sc,oldColor,newColor);returnimg;}//Driver Code StartsstaticvoidMain(){int[,]img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;int[,]result=floodFill(img,sr,sc,newColor);for(inti=0;i<result.GetLength(0);i++){for(intj=0;j<result.GetLength(1);j++){Console.Write(result[i,j]+" ");}Console.WriteLine();}}}//Driver Code Ends
JavaScript
functiondfs(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 pixelimg[x][y]=newColor;// Recursively visit all 4 connected neighborsdfs(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);}functionfloodFill(img,sr,sc,newColor){// If the starting pixel already has the new color,// no changes are neededif(img[sr][sc]===newColor){returnimg;}// Call DFS to start filling from the source pixel// Store original colorletoldColor=img[sr][sc];dfs(img,sr,sc,oldColor,newColor);returnimg;}//Driver Code Starts//Driver Codeletimg=[[1,1,1,0],[0,1,1,1],[1,0,1,1]];letsr=1,sc=2;letnewColor=2;letresult=floodFill(img,sr,sc,newColor);for(letrowofresult){console.log(row.join(" "));}//Driver Code Ends
Output
2 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>usingnamespacestd;//Driver Code Endsvector<vector<int>>floodFill(vector<vector<int>>&img,intsr,intsc,intnewColor){// If the starting pixel already has the new colorif(img[sr][sc]==newColor){returnimg;}// Direction vectors for traversing 4 directionsvector<pair<int,int>>dir={{1,0},{-1,0},{0,1},{0,-1}};queue<pair<int,int>>q;intoldColor=img[sr][sc];q.push({sr,sc});// Change the color of the starting pixelimg[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(pair<int,int>&it:dir){intnx=x+it.first;intny=y+it.second;// Check boundary conditions and color matchif(nx>=0&&nx<img.size()&&ny>=0&&ny<img[0].size()&&img[nx][ny]==oldColor){img[nx][ny]=newColor;q.push({nx,ny});}}}returnimg;}//Driver Code Startsintmain(){vector<vector<int>>img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;vector<vector<int>>result=floodFill(img,sr,sc,newColor);for(auto&row:result){for(auto&pixel:row){cout<<pixel<<" ";}cout<<"";}return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.Queue;importjava.util.LinkedList;publicclassGFG{//Driver Code Endspublicstaticint[][]floodFill(int[][]img,intsr,intsc,intnewColor){// If the starting pixel already has the new colorif(img[sr][sc]==newColor){returnimg;}// Direction vectors for traversing 4 directionsint[][]dir={{1,0},{-1,0},{0,1},{0,-1}};Queue<int[]>q=newLinkedList<>();intoldColor=img[sr][sc];q.add(newint[]{sr,sc});// Change the color of the starting pixelimg[sr][sc]=newColor;// Perform BFSwhile(!q.isEmpty()){int[]front=q.poll();intx=front[0],y=front[1];// Traverse all 4 directionsfor(int[]it:dir){intnx=x+it[0];intny=y+it[1];// Check boundary conditions and color matchif(nx>=0&&nx<img.length&&ny>=0&&ny<img[0].length&&img[nx][ny]==oldColor){img[nx][ny]=newColor;q.add(newint[]{nx,ny});}}}returnimg;}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;int[][]result=floodFill(img,sr,sc,newColor);for(int[]row:result){for(intpixel:row){System.out.print(pixel+" ");}System.out.println();}}}//Driver Code Ends
Python
#Driver Code Startsfromcollectionsimportdeque#Driver Code EndsdeffloodFill(img,sr,sc,newColor):# If the starting pixel already has the new colorifimg[sr][sc]==newColor:returnimg# Direction vectors for traversing 4 directionsdir=[(1,0),(-1,0),(0,1),(0,-1)]q=deque()oldColor=img[sr][sc]q.append((sr,sc))# Change the color of the starting pixelimg[sr][sc]=newColor# Perform BFSwhileq:x,y=q.popleft()# Traverse all 4 directionsfordx,dyindir:nx=x+dxny=y+dy# Check boundary conditions and color matchif0<=nx<len(img)and0<=ny<len(img[0])andimg[nx][ny]==oldColor:img[nx][ny]=newColorq.append((nx,ny))returnimg#Driver Code Startsif__name__=="__main__":img=[[1,1,1,0],[0,1,1,1],[1,0,1,1]]sr,sc=1,2newColor=2result=floodFill(img,sr,sc,newColor)forrowinresult:print(*row)#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;classGFG{//Driver Code Endspublicstaticint[,]floodFill(int[,]img,intsr,intsc,intnewColor){// If the starting pixel already has the new colorif(img[sr,sc]==newColor)returnimg;// Direction vectors for traversing 4 directionsint[,]dir={{1,0},{-1,0},{0,1},{0,-1}};Queue<(int,int)>q=newQueue<(int,int)>();intoldColor=img[sr,sc];q.Enqueue((sr,sc));// Change the color of the starting pixelimg[sr,sc]=newColor;intn=img.GetLength(0);intm=img.GetLength(1);// Perform BFSwhile(q.Count>0){var(x,y)=q.Dequeue();// Traverse all 4 directionsfor(inti=0;i<4;i++){intnx=x+dir[i,0];intny=y+dir[i,1];// Check boundary conditions and color matchif(nx>=0&&nx<n&&ny>=0&&ny<m&&img[nx,ny]==oldColor){img[nx,ny]=newColor;q.Enqueue((nx,ny));}}}returnimg;}//Driver Code StartsstaticvoidMain(){int[,]img={{1,1,1,0},{0,1,1,1},{1,0,1,1}};intsr=1,sc=2;intnewColor=2;int[,]result=floodFill(img,sr,sc,newColor);intn=result.GetLength(0);intm=result.GetLength(1);for(inti=0;i<n;i++){for(intj=0;j<m;j++){Console.Write(result[i,j]+" ");}Console.WriteLine();}}}//Driver Code Ends
JavaScript
functionfloodFill(img,sr,sc,newColor){// If the starting pixel already has the new colorif(img[sr][sc]===newColor)returnimg;// Direction vectors for traversing 4 directionsconstdir=[[1,0],[-1,0],[0,1],[0,-1]];constq=[];constoldColor=img[sr][sc];q.push([sr,sc]);// Change the color of the starting pixelimg[sr][sc]=newColor;// Perform BFSwhile(q.length>0){const[x,y]=q.shift();// Traverse all 4 directionsfor(constitofdir){constnx=x+it[0];constny=y+it[1];// Check boundary conditions and color matchif(nx>=0&&nx<img.length&&ny>=0&&ny<img[0].length&&img[nx][ny]===oldColor){img[nx][ny]=newColor;q.push([nx,ny]);}}}returnimg;}//Driver Code//Driver Code Startsconstimg=[[1,1,1,0],[0,1,1,1],[1,0,1,1]];constsr=1,sc=2,newColor=2;constresult=floodFill(img,sr,sc,newColor);result.forEach(row=>console.log(row.join(" ")));//Driver Code Ends