Given a matrix mat[][] of size n x m, where mat[i][j] represents the signal strength of a communication tower. Two control stations monitor the network:
Station P covers the top and left boundaries of the grid.
Station Q covers the bottom and right boundaries of the grid.
A signal can propagate from a tower to one of its neighbouring towers in the four directions (North, South, East, and West) only if the neighbouring tower has a signal strength less than or equal to that of the current tower.
Determine the number of towers (x, y) from which a signal can eventually reach both Station P and Station Q. Any tower located on a boundary covered by a station can transmit directly to that station.
In the given matrix, there are 7 coordinates through which the signals can propagate to both the stations. They are (0, 4), (1, 3), (1, 4), (2, 2), (3, 0), (3, 1), and (4, 0).
Input: mat[][] = [[2, 2], [2, 2]] Output: 4 Explanation: In the following example, all cells allow signals to propagate to both the stations.
[Naive Approach] Using DFS/BFS from Every Cell - O((n * m) ^ 2) Time and O(n * m) Space
The idea is to start a DFS from every tower and move only to adjacent towers having signal strength less than or equal to the current tower. During the traversal, check whether the signal reaches both Station P and Station Q. Count all such towers.
Working of Approach:
Treat each cell as a signal source and perform a DFS to explore all cells that can be reached by moving to adjacent cells with value less than or equal to the current cell.
During traversal, keep track of whether the signal reaches Station P (top row or left column) and Station Q (bottom row or right column).
For every starting cell, use a separate visited matrix to avoid revisiting cells in the same DFS traversal.
After completing the DFS, if the signal can reach both stations, increment the answer count.
Finally, return the total number of cells from which the signal can reach both Station P and Station Q.
C++
#include<iostream>#include<vector>usingnamespacestd;voiddfs(introw,intcol,vector<vector<int>>&mat,vector<vector<bool>>&vis,bool&stationP,bool&stationQ){intn=mat.size();intm=mat[0].size();vis[row][col]=true;// Signal reaches Station Pif(row==0||col==0)stationP=true;// Signal reaches Station Qif(row==n-1||col==m-1)stationQ=true;intdr[]={-1,1,0,0};intdc[]={0,0,-1,1};for(intk=0;k<4;k++){intnewRow=row+dr[k];intnewCol=col+dc[k];if(newRow>=0&&newRow<n&&newCol>=0&&newCol<m&&!vis[newRow][newCol]&&mat[newRow][newCol]<=mat[row][col]){dfs(newRow,newCol,mat,vis,stationP,stationQ);}}}intcountCoordinates(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();intans=0;// Start DFS from every cellfor(inti=0;i<n;i++){for(intj=0;j<m;j++){vector<vector<bool>>vis(n,vector<bool>(m,false));boolstationP=false;boolstationQ=false;dfs(i,j,mat,vis,stationP,stationQ);if(stationP&&stationQ)ans++;}}returnans;}intmain(){vector<vector<int>>mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};cout<<countCoordinates(mat)<<endl;return0;}
Java
importjava.util.Arrays;publicclassGFG{staticvoiddfs(introw,intcol,int[][]mat,boolean[][]vis,boolean[]station){intn=mat.length;intm=mat[0].length;vis[row][col]=true;// Signal reaches Station Pif(row==0||col==0)station[0]=true;// Signal reaches Station Qif(row==n-1||col==m-1)station[1]=true;int[]dr={-1,1,0,0};int[]dc={0,0,-1,1};for(intk=0;k<4;k++){intnewRow=row+dr[k];intnewCol=col+dc[k];if(newRow>=0&&newRow<n&&newCol>=0&&newCol<m&&!vis[newRow][newCol]&&mat[newRow][newCol]<=mat[row][col]){dfs(newRow,newCol,mat,vis,station);}}}staticintcountCoordinates(int[][]mat){intn=mat.length;intm=mat[0].length;intans=0;// Start DFS from every cellfor(inti=0;i<n;i++){for(intj=0;j<m;j++){boolean[][]vis=newboolean[n][m];boolean[]station={false,false};dfs(i,j,mat,vis,station);if(station[0]&&station[1])ans++;}}returnans;}publicstaticvoidmain(String[]args){int[][]mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};System.out.println(countCoordinates(mat));}}
Python
defdfs(row,col,mat,vis,station):n=len(mat)m=len(mat[0])vis[row][col]=True# Signal reaches Station Pifrow==0orcol==0:station[0]=True# Signal reaches Station Qifrow==n-1orcol==m-1:station[1]=Truedr=[-1,1,0,0]dc=[0,0,-1,1]forkinrange(4):newRow=row+dr[k]newCol=col+dc[k]if0<=newRow<nand0<=newCol<mandnotvis[newRow][newCol]andmat[newRow][newCol]<=mat[row][col]:dfs(newRow,newCol,mat,vis,station)defcountCoordinates(mat):n=len(mat)m=len(mat[0])ans=0# Start DFS from every cellforiinrange(n):forjinrange(m):vis=[[False]*mfor_inrange(n)]station=[False,False]dfs(i,j,mat,vis,station)ifstation[0]andstation[1]:ans+=1returnansif__name__=="__main__":mat=[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]print(countCoordinates(mat))
C#
usingSystem;publicclassGFG{staticvoiddfs(introw,intcol,int[,]mat,bool[,]vis,bool[]station){intn=mat.GetLength(0);intm=mat.GetLength(1);vis[row,col]=true;// Signal reaches Station Pif(row==0||col==0)station[0]=true;// Signal reaches Station Qif(row==n-1||col==m-1)station[1]=true;int[]dr={-1,1,0,0};int[]dc={0,0,-1,1};for(intk=0;k<4;k++){intnewRow=row+dr[k];intnewCol=col+dc[k];if(newRow>=0&&newRow<n&&newCol>=0&&newCol<m&&!vis[newRow,newCol]&&mat[newRow,newCol]<=mat[row,col]){dfs(newRow,newCol,mat,vis,station);}}}staticintcountCoordinates(int[,]mat){intn=mat.GetLength(0);intm=mat.GetLength(1);intans=0;// Start DFS from every cellfor(inti=0;i<n;i++){for(intj=0;j<m;j++){bool[,]vis=newbool[n,m];bool[]station={false,false};dfs(i,j,mat,vis,station);if(station[0]&&station[1])ans++;}}returnans;}publicstaticvoidMain(){int[,]mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};Console.WriteLine(countCoordinates(mat));}}
JavaScript
functiondfs(row,col,mat,vis,station){constn=mat.length;constm=mat[0].length;vis[row][col]=true;// Signal reaches Station Pif(row===0||col===0)station[0]=true;// Signal reaches Station Qif(row===n-1||col===m-1)station[1]=true;constdr=[-1,1,0,0];constdc=[0,0,-1,1];for(letk=0;k<4;k++){constnewRow=row+dr[k];constnewCol=col+dc[k];if(newRow>=0&&newRow<n&&newCol>=0&&newCol<m&&!vis[newRow][newCol]&&mat[newRow][newCol]<=mat[row][col]){dfs(newRow,newCol,mat,vis,station);}}}functioncountCoordinates(mat){constn=mat.length;constm=mat[0].length;letans=0;// Start DFS from every cellfor(leti=0;i<n;i++){for(letj=0;j<m;j++){constvis=Array.from({length:n},()=>Array(m).fill(false));conststation=[false,false];dfs(i,j,mat,vis,station);if(station[0]&&station[1])ans++;}}returnans;}// Driver Codeconstmat=[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]];console.log(countCoordinates(mat));
Output
7
[Expected Approach] Reverse BFS from Both Stations - O(n * m) Time and O(n * m) Space
The idea is to perform two reverse BFS traversals starting from the boundary cells of both stations. During traversal, move only to adjacent cells with greater than or equal signal strength, mark the reachable cells for each station, and finally count the cells reachable from both stations.
Let us understand with an example: Input: mat[][] = [[1, 2, 2, 3, 5], [3, 2, 3, 4, 4], [2, 4, 5, 3, 1], [6, 7, 1, 4, 5], [5, 1, 1, 2, 4]]
Start a reverse BFS from the top and left boundaries to mark all cells reachable from Station P.
Similarly, perform another reverse BFS from the bottom and right boundaries to mark all cells reachable from Station Q.
A cell is considered valid only if it is marked as reachable in both traversals.
The common reachable cells are (0,4), (1,3), (1,4), (2,2), (3,0), (3,1), and (4,0).
Hence, the total number of such cells is 7.
C++
#include<iostream>#include<queue>#include<utility>#include<vector>usingnamespacestd;// Direction vectors for moving right, left, up and downintdx[4]={0,0,-1,1};intdy[4]={1,-1,0,0};// Check whether a cell lies inside the gridboolisValid(introw,intcol,intn,intm){returnrow>=0&&col>=0&&row<n&&col<m;}// BFS to find towers reachable from a control stationvoidbfs(vector<vector<int>>&strength,intn,intm,queue<pair<int,int>>&q,vector<vector<bool>>&reachable){while(!q.empty()){auto[row,col]=q.front();q.pop();// Visit all neighbouring towersfor(intk=0;k<4;k++){intnewRow=row+dx[k];intnewCol=col+dy[k];// Signal can propagate only to towers having// strength greater than or equal to the current towerif(isValid(newRow,newCol,n,m)&&!reachable[newRow][newCol]&&strength[newRow][newCol]>=strength[row][col]){reachable[newRow][newCol]=true;q.push({newRow,newCol});}}}}intcountCoordinates(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();queue<pair<int,int>>stationP,stationQ;// Stores towers reachable from Station P and Station Qvector<vector<bool>>reachP(n,vector<bool>(m,false));vector<vector<bool>>reachQ(n,vector<bool>(m,false));// Towers adjacent to Station P (top boundary)// and Station Q (bottom boundary)for(intj=0;j<m;j++){stationP.push({0,j});reachP[0][j]=true;stationQ.push({n-1,j});reachQ[n-1][j]=true;}// Towers adjacent to Station P (left boundary)// and Station Q (right boundary)for(inti=0;i<n;i++){stationP.push({i,0});reachP[i][0]=true;stationQ.push({i,m-1});reachQ[i][m-1]=true;}// Run BFS from both stationsbfs(mat,n,m,stationP,reachP);bfs(mat,n,m,stationQ,reachQ);intcount=0;// Count towers reachable from both stationsfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(reachP[i][j]&&reachQ[i][j]){count++;}}}returncount;}intmain(){vector<vector<int>>mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};cout<<countCoordinates(mat)<<endl;return0;}
Java
importjava.util.*;classGFG{// Direction vectors for moving right, left, up and downstaticint[]dx={0,0,-1,1};staticint[]dy={1,-1,0,0};// Check whether a cell lies inside the gridstaticbooleanisValid(introw,intcol,intn,intm){returnrow>=0&&col>=0&&row<n&&col<m;}// BFS to find towers reachable from a control stationstaticvoidbfs(int[][]strength,intn,intm,Queue<int[]>q,boolean[][]reachable){while(!q.isEmpty()){int[]curr=q.poll();introw=curr[0];intcol=curr[1];// Visit all neighbouring towersfor(intk=0;k<4;k++){intnewRow=row+dx[k];intnewCol=col+dy[k];// Signal can propagate only to towers// having strength greater than or equal to// the current towerif(isValid(newRow,newCol,n,m)&&!reachable[newRow][newCol]&&strength[newRow][newCol]>=strength[row][col]){reachable[newRow][newCol]=true;q.offer(newint[]{newRow,newCol});}}}}staticintcountCoordinates(int[][]mat){intn=mat.length;intm=mat[0].length;Queue<int[]>stationP=newLinkedList<>();Queue<int[]>stationQ=newLinkedList<>();// Stores towers reachable from Station P and// Station Qboolean[][]reachP=newboolean[n][m];boolean[][]reachQ=newboolean[n][m];// Towers adjacent to Station P (top boundary)// and Station Q (bottom boundary)for(intj=0;j<m;j++){stationP.offer(newint[]{0,j});reachP[0][j]=true;stationQ.offer(newint[]{n-1,j});reachQ[n-1][j]=true;}// Towers adjacent to Station P (left boundary)// and Station Q (right boundary)for(inti=0;i<n;i++){stationP.offer(newint[]{i,0});reachP[i][0]=true;stationQ.offer(newint[]{i,m-1});reachQ[i][m-1]=true;}// Run BFS from both stationsbfs(mat,n,m,stationP,reachP);bfs(mat,n,m,stationQ,reachQ);intcount=0;// Count towers reachable from both stationsfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(reachP[i][j]&&reachQ[i][j]){count++;}}}returncount;}publicstaticvoidmain(String[]args){int[][]mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};System.out.println(countCoordinates(mat));}}
Python
fromcollectionsimportdeque# Direction vectors for moving right, left, up and downdx=[0,0,-1,1]dy=[1,-1,0,0]# Check whether a cell lies inside the griddefisValid(row,col,n,m):return0<=row<nand0<=col<m# BFS to find towers reachable from a control stationdefbfs(strength,n,m,q,reachable):whileq:row,col=q.popleft()# Visit all neighbouring towersforkinrange(4):newRow=row+dx[k]newCol=col+dy[k]# Signal can propagate only to towers having# strength greater than or equal to the current towerif(isValid(newRow,newCol,n,m)andnotreachable[newRow][newCol]andstrength[newRow][newCol]>=strength[row][col]):reachable[newRow][newCol]=Trueq.append((newRow,newCol))defcountCoordinates(mat):n=len(mat)m=len(mat[0])stationP=deque()stationQ=deque()# Stores towers reachable from Station P and Station QreachP=[[False]*mfor_inrange(n)]reachQ=[[False]*mfor_inrange(n)]# Towers adjacent to Station P (top boundary)# and Station Q (bottom boundary)forjinrange(m):stationP.append((0,j))reachP[0][j]=TruestationQ.append((n-1,j))reachQ[n-1][j]=True# Towers adjacent to Station P (left boundary)# and Station Q (right boundary)foriinrange(n):stationP.append((i,0))reachP[i][0]=TruestationQ.append((i,m-1))reachQ[i][m-1]=True# Run BFS from both stationsbfs(mat,n,m,stationP,reachP)bfs(mat,n,m,stationQ,reachQ)count=0# Count towers reachable from both stationsforiinrange(n):forjinrange(m):ifreachP[i][j]andreachQ[i][j]:count+=1returncountif__name__=="__main__":mat=[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]print(countCoordinates(mat))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Direction vectors for moving right, left, up and downstaticint[]dx={0,0,-1,1};staticint[]dy={1,-1,0,0};// Check whether a cell lies inside the gridstaticboolisValid(introw,intcol,intn,intm){returnrow>=0&&col>=0&&row<n&&col<m;}// BFS to find towers reachable from a control stationstaticvoidbfs(int[,]strength,intn,intm,Queue<(int,int)>q,bool[,]reachable){while(q.Count>0){var(row,col)=q.Dequeue();// Visit all neighbouring towersfor(intk=0;k<4;k++){intnewRow=row+dx[k];intnewCol=col+dy[k];// Signal can propagate only to towers// having strength greater than or equal to// the current towerif(isValid(newRow,newCol,n,m)&&!reachable[newRow,newCol]&&strength[newRow,newCol]>=strength[row,col]){reachable[newRow,newCol]=true;q.Enqueue((newRow,newCol));}}}}staticintcountCoordinates(int[,]mat){intn=mat.GetLength(0);intm=mat.GetLength(1);Queue<(int,int)>stationP=newQueue<(int,int)>();Queue<(int,int)>stationQ=newQueue<(int,int)>();// Stores towers reachable from Station P and// Station Qbool[,]reachP=newbool[n,m];bool[,]reachQ=newbool[n,m];// Towers adjacent to Station P (top boundary)// and Station Q (bottom boundary)for(intj=0;j<m;j++){stationP.Enqueue((0,j));reachP[0,j]=true;stationQ.Enqueue((n-1,j));reachQ[n-1,j]=true;}// Towers adjacent to Station P (left boundary)// and Station Q (right boundary)for(inti=0;i<n;i++){stationP.Enqueue((i,0));reachP[i,0]=true;stationQ.Enqueue((i,m-1));reachQ[i,m-1]=true;}// Run BFS from both stationsbfs(mat,n,m,stationP,reachP);bfs(mat,n,m,stationQ,reachQ);intcount=0;// Count towers reachable from both stationsfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(reachP[i,j]&&reachQ[i,j]){count++;}}}returncount;}staticvoidMain(){int[,]mat={{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};Console.WriteLine(countCoordinates(mat));}}
JavaScript
// Direction vectors for moving right, left, up and downconstdx=[0,0,-1,1];constdy=[1,-1,0,0];// Check whether a cell lies inside the gridfunctionisValid(row,col,n,m){returnrow>=0&&col>=0&&row<n&&col<m;}// BFS to find towers reachable from a control stationfunctionbfs(strength,n,m,queue,reachable){letfront=0;while(front<queue.length){const[row,col]=queue[front++];// Visit all neighbouring towersfor(letk=0;k<4;k++){constnewRow=row+dx[k];constnewCol=col+dy[k];// Signal can propagate only to towers having// strength greater than or equal to the current// towerif(isValid(newRow,newCol,n,m)&&!reachable[newRow][newCol]&&strength[newRow][newCol]>=strength[row][col]){reachable[newRow][newCol]=true;queue.push([newRow,newCol]);}}}}functioncountCoordinates(mat){constn=mat.length;constm=mat[0].length;conststationP=[];conststationQ=[];// Stores towers reachable from Station P and Station QconstreachP=Array.from({length:n},()=>Array(m).fill(false));constreachQ=Array.from({length:n},()=>Array(m).fill(false));// Towers adjacent to Station P (top boundary)// and Station Q (bottom boundary)for(letj=0;j<m;j++){stationP.push([0,j]);reachP[0][j]=true;stationQ.push([n-1,j]);reachQ[n-1][j]=true;}// Towers adjacent to Station P (left boundary)// and Station Q (right boundary)for(leti=0;i<n;i++){stationP.push([i,0]);reachP[i][0]=true;stationQ.push([i,m-1]);reachQ[i][m-1]=true;}// Run BFS from both stationsbfs(mat,n,m,stationP,reachP);bfs(mat,n,m,stationQ,reachQ);letcount=0;// Count towers reachable from both stationsfor(leti=0;i<n;i++){for(letj=0;j<m;j++){if(reachP[i][j]&&reachQ[i][j]){count++;}}}returncount;}// Driver codeconstmat=[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]];console.log(countCoordinates(mat));