There is an N x M rectangular island that borders both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean touches the island’s left and top edges, and the Atlantic Ocean touches the island’s right and bottom edges.
The island is partitioned into a grid of square cells. The island receives a lot of rain, and the rainwater can flow to neighboring cells directly north, south, east, and west if the neighboring cell’s height is less than or equal to the current cell’s height. Water can flow from any cell adjacent to an ocean into the ocean.
Given a matrix mat[][] having N rows and M columns where mat[x][y] represents the height above sea level of the cell at coordinate (x, y), the task is to find the number of coordinates (x, y) such that the rainwater can flow from the cell (x, y) to both the Pacific and Atlantic oceans.
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}}Output: 7
Explanation: In the given matrix, there are 7 coordinates through which the water can flow to both the lakes. 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
Example: In the following example, all cells allow water to flow to both the lakes.
Approach: The given problem can be solved using either a DFS or a BFS traversal. The idea is to mark all the cells that are reachable from the directly connected cells from the Pacific and the Atlantic Oceans separately using either DFS or BFS. The count of cells that are connected through both is the required answer. Below are the steps to follow:
- Create two queues q1 and q2 in order to store the coordinates of the matrix as a pair.
- Traverse the whole matrix and store coordinates directly connected to the Pacific Ocean to q1 and perform a BFS traversal from all the coordinates in q1 and mark them visited.
- Similarly, traverse the whole matrix and store coordinates directly connected to the Atlantic Ocean to q2 and perform a BFS traversal from all the coordinates in q2 and mark them visited.
- Traverse the given matrix mat[][] and maintain the count of coordinates that are visited during both the traversals.
Below is the implementation of the above approach:
// C++ Program of the above approach #include <bits/stdc++.h> using namespace std;
int x[5] = { 0, 0, -1, 1 };
int y[5] = { 1, -1, 0, 0 };
// Function to check if coordinate // (i, j) lies inside N x M matrix bool safe( int i, int j, int N, int M)
{ if (i < 0 || j < 0 || i >= N || j >= M)
return false ;
return true ;
} // Function to perform a BFS // Traversal and mark visited void BFS(vector<vector< int > > matrix, int N, int M,
queue<pair< int , int > > q,
vector<vector< bool > >& vis)
{ // Loop to traverse q
while (q.empty() == false ) {
// Stores current coordinate
pair< int , int > cur = q.front();
q.pop();
// Mark current visited
vis[cur.first][cur.second] = true ;
for ( int i = 0; i < 4; i++) {
int nx = cur.first + x[i];
int ny = cur.second + y[i];
// If coordinate (nx, ny)
// is inbound and rechable
if (safe(nx, ny, N, M)
&& matrix[nx][ny]
>= matrix[cur.first]
[cur.second]
&& vis[nx][ny] == false ) {
// Insert into queue
q.push({ nx, ny });
// Mark visited
vis[nx][ny] = true ;
}
}
}
} // Function to find the count of // valid coordinates int countCoordinates(vector<vector< int > > mat,
int N, int M)
{ // Queue to perform BFS
queue<pair< int , int > > q1, q2;
// Stores the visited coordinates
// during the 1st traversal
vector<vector< bool > > visited1(
N,
vector< bool >(M, false ));
// Stores the visited coordinates
// during the 2nd traversal
vector<vector< bool > > visited2(
N,
vector< bool >(M, false ));
// Insert the coordinates
// directly connected
for ( int i = 0; i < M; i++) {
q1.push({ 0, i });
q2.push({ N - 1, i });
}
for ( int j = 0; j < N - 1; j++) {
q1.push({ j + 1, 0 });
q2.push({ j, M - 1 });
}
// BFS for the 1st ocean
BFS(mat, N, M, q1, visited1);
// BFS for the 2nd ocean
BFS(mat, N, M, q2, visited2);
// Stores the required count
int ans = 0;
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
// If coordinate (i, j)
// is reachable from both
if (visited1[i][j]
&& visited2[i][j]) {
// Update count
ans++;
}
}
}
// Return Answer
return ans;
} // Driver code int main()
{ 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, mat.size(),
mat[0].size());
return 0;
} |
// Java Program of the above approach import java.util.*;
class GFG{
static int x[] = { 0 , 0 , - 1 , 1 };
static int y[] = { 1 , - 1 , 0 , 0 };
static class pair
{ int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
} // Function to check if coordinate // (i, j) lies inside N x M matrix static boolean safe( int i, int j, int N, int M)
{ if (i < 0 || j < 0 || i >= N || j >= M)
return false ;
return true ;
} // Function to perform a BFS // Traversal and mark visited static void BFS( int [][] matrix, int N, int M,
Queue<pair> q,
boolean [][]vis)
{ // Loop to traverse q
while (q.isEmpty() == false ) {
// Stores current coordinate
pair cur = q.peek();
q.remove();
// Mark current visited
vis[cur.first][cur.second] = true ;
for ( int i = 0 ; i < 4 ; i++) {
int nx = cur.first + x[i];
int ny = cur.second + y[i];
// If coordinate (nx, ny)
// is inbound and rechable
if (safe(nx, ny, N, M)
&& matrix[nx][ny]
>= matrix[cur.first]
[cur.second]
&& vis[nx][ny] == false ) {
// Insert into queue
q.add( new pair( nx, ny ));
// Mark visited
vis[nx][ny] = true ;
}
}
}
} // Function to find the count of // valid coordinates static int countCoordinates( int [][] mat,
int N, int M)
{ // Queue to perform BFS
Queue<pair > q1 = new LinkedList<>();
Queue<pair > q2 = new LinkedList<>();
// Stores the visited coordinates
// during the 1st traversal
boolean visited1[][] = new boolean [N][M];
// Stores the visited coordinates
// during the 2nd traversal
boolean visited2[][] = new boolean [N][M];
// Insert the coordinates
// directly connected
for ( int i = 0 ; i < M; i++) {
q1.add( new pair( 0 , i ));
q2.add( new pair( N - 1 , i ));
}
for ( int j = 0 ; j < N - 1 ; j++) {
q1.add( new pair( j + 1 , 0 ));
q2.add( new pair( j, M - 1 ));
}
// BFS for the 1st ocean
BFS(mat, N, M, q1, visited1);
// BFS for the 2nd ocean
BFS(mat, N, M, q2, visited2);
// Stores the required count
int ans = 0 ;
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
// If coordinate (i, j)
// is reachable from both
if (visited1[i][j]
&& visited2[i][j]) {
// Update count
ans++;
}
}
}
// Return Answer
return ans;
} // Driver code public static void main(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.print(countCoordinates(mat, mat[ 0 ].length,
mat[ 1 ].length));
} } // This code contributed by shikhasingrajput |
Steps = [
[ - 1 , 0 ], # Up
[ 0 , 1 ], # Right
[ 1 , 0 ], # bottom
[ 0 , - 1 ] # Left
]
def withinLimits(row_num, col_num, total_rows, total_cols):
if 0 < = row_num < total_rows and 0 < = col_num < total_cols:
return True
return False
def waterSlope(oceanMatrix, matrix, row, col):
nrows, ncols = len (matrix), len (matrix[ 0 ])
for i in Steps:
if withinLimits(row + i[ 0 ], col + i[ 1 ], nrows, ncols):
if matrix[row + i[ 0 ]][col + i[ 1 ]] > = matrix[row][col] and not oceanMatrix[row + i[ 0 ]][col + i[ 1 ]]:
oceanMatrix[row + i[ 0 ]][col + i[ 1 ]] = True
waterSlope(oceanMatrix, matrix, row + i[ 0 ], col + i[ 1 ])
def commonWaterFlow(matrix):
matrix_rows = len (matrix)
matrix_cols = len (matrix[ 0 ])
pacificMatrix = [[ False for _ in range (matrix_cols)] for _ in range (matrix_rows)]
atlanticMatrix = [[ False for _ in range (matrix_cols)] for _ in range (matrix_rows)]
pacificMatrix[ 0 ][ 1 ] = True
pacificMatrix[ 0 ][ 2 ] = True
for i in range (matrix_cols):
pacificMatrix[ 0 ][i] = True
atlanticMatrix[(matrix_rows - 1 )][i] = True
for i in range (matrix_rows):
pacificMatrix[i][ 0 ] = True
atlanticMatrix[i][(matrix_cols - 1 )] = True
for i in range (matrix_cols):
waterSlope(pacificMatrix, matrix, 0 , i)
waterSlope(atlanticMatrix, matrix, matrix_rows - 1 , i)
for i in range (matrix_rows):
waterSlope(pacificMatrix, matrix, i, 0 )
waterSlope(atlanticMatrix, matrix, i, matrix_cols - 1 )
Count = 0
for i in range (matrix_rows):
for j in range (matrix_cols):
if pacificMatrix[i][j] and atlanticMatrix[i][j]:
Count + = 1
return Count
mat = [ [ 1 , 2 , 2 , 3 , 5 ], # T-T-T-T-T F-F-F-F-T
[ 3 , 2 , 3 , 4 , 4 ], # T-T-T-T-T F-F-F-T-T
[ 2 , 4 , 5 , 3 , 1 ], # T-T-T-F-F F-F-T-T-T
[ 6 , 7 , 1 , 4 , 5 ], # T-T-F-F-F T-T-T-T-T
[ 5 , 1 , 1 , 2 , 4 ] ] # T-F-F-F-F T-T-T-T-T
print (commonWaterFlow(mat))
|
// C# Program of the above approach using System;
using System.Collections.Generic;
public class GFG{
static int []x = { 0, 0, -1, 1 };
static int []y = { 1, -1, 0, 0 };
class pair
{ public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
} // Function to check if coordinate // (i, j) lies inside N x M matrix static bool safe( int i, int j, int N, int M)
{ if (i < 0 || j < 0 || i >= N || j >= M)
return false ;
return true ;
} // Function to perform a BFS // Traversal and mark visited static void BFS( int [,] matrix, int N, int M,
Queue<pair> q,
bool [,]vis)
{ // Loop to traverse q
while (q.Count!=0 ) {
// Stores current coordinate
pair cur = q.Peek();
q.Dequeue();
// Mark current visited
vis[cur.first,cur.second] = true ;
for ( int i = 0; i < 4; i++) {
int nx = cur.first + x[i];
int ny = cur.second + y[i];
// If coordinate (nx, ny)
// is inbound and rechable
if (safe(nx, ny, N, M)
&& matrix[nx,ny]
>= matrix[cur.first,cur.second]
&& vis[nx,ny] == false ) {
// Insert into queue
q.Enqueue( new pair( nx, ny ));
// Mark visited
vis[nx,ny] = true ;
}
}
}
} // Function to find the count of // valid coordinates static int countCoordinates( int [,] mat,
int N, int M)
{ // Queue to perform BFS
Queue<pair > q1 = new Queue<pair >();
Queue<pair > q2 = new Queue<pair >();
// Stores the visited coordinates
// during the 1st traversal
bool [,]visited1 = new bool [N,M];
// Stores the visited coordinates
// during the 2nd traversal
bool [,]visited2 = new bool [N,M];
// Insert the coordinates
// directly connected
for ( int i = 0; i < M; i++) {
q1.Enqueue( new pair( 0, i ));
q2.Enqueue( new pair( N - 1, i ));
}
for ( int j = 0; j < N - 1; j++) {
q1.Enqueue( new pair( j + 1, 0 ));
q2.Enqueue( new pair( j, M - 1 ));
}
// BFS for the 1st ocean
BFS(mat, N, M, q1, visited1);
// BFS for the 2nd ocean
BFS(mat, N, M, q2, visited2);
// Stores the required count
int ans = 0;
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
// If coordinate (i, j)
// is reachable from both
if (visited1[i,j]
&& visited2[i,j]) {
// Update count
ans++;
}
}
}
// Return Answer
return ans;
} // Driver code public static void Main(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 } };
Console.Write(countCoordinates(mat, mat.GetLength(0),
mat.GetLength(1)));
} } // This code contributed by shikhasingrajput |
const Steps = [ [-1, 0], // Up
[0, 1], // Right
[1, 0], // Bottom
[0, -1] // Left
]; function withinLimits(row_num, col_num, total_rows, total_cols) {
return row_num >= 0 && row_num < total_rows && col_num >= 0 &&
col_num < total_cols;
} function waterSlope(oceanMatrix, matrix, row, col) {
const nrows = matrix.length, ncols = matrix[0].length;
for (const [r, c] of Steps) {
if (withinLimits(row+r, col+c, nrows, ncols)) {
if (matrix[row+r][col+c] >= matrix[row][col] &&
!oceanMatrix[row+r][col+c]) {
oceanMatrix[row+r][col+c] = true ;
waterSlope(oceanMatrix, matrix, row+r, col+c);
}
}
}
} function commonWaterFlow(matrix) {
const matrix_rows = matrix.length, matrix_cols = matrix[0].length;
const pacificMatrix = Array.from({length: matrix_rows},
() => Array(matrix_cols).fill( false ));
const atlanticMatrix = Array.from({length: matrix_rows},
() => Array(matrix_cols).fill( false ));
pacificMatrix[0][1] = true ;
pacificMatrix[0][2] = true ;
for (let i = 0; i < matrix_cols; i++) {
pacificMatrix[0][i] = true ;
atlanticMatrix[(matrix_rows-1)][i] = true ;
}
for (let i = 0; i < matrix_rows; i++) {
pacificMatrix[i][0] = true ;
atlanticMatrix[i][(matrix_cols-1)] = true ;
}
for (let i = 0; i < matrix_cols; i++) {
waterSlope(pacificMatrix, matrix, 0, i);
waterSlope(atlanticMatrix, matrix, matrix_rows-1, i);
}
for (let i = 0; i < matrix_rows; i++) {
waterSlope(pacificMatrix, matrix, i, 0);
waterSlope(atlanticMatrix, matrix, i, matrix_cols-1);
}
let Count = 0;
for (let i = 0; i < matrix_rows; i++) {
for (let j = 0; j < matrix_cols; j++) {
if (pacificMatrix[i][j] && atlanticMatrix[i][j]) {
Count++;
}
}
}
return Count;
} const mat = [ [1, 2, 2, 3, 5], // T-T-T-T-T F-F-F-F-T
[3, 2, 3, 4, 4], // T-T-T-T-T F-F-F-T-T
[2, 4, 5, 3, 1], // T-T-T-F-F F-F-T-T-T
[6, 7, 1, 4, 5], // T-T-F-F-F T-T-T-T-T
[5, 1, 1, 2, 4] // T-F-F-F-F T-T-T-T-T
]; console.log(commonWaterFlow(mat)); // This code is contributed by Prince Kumar |
7
Time Complexity: O(N*M)
Auxiliary Space: O(N*M)