Given an N x N binary matrix grid, where 0 represents a sea cell and 1 represents a land cell. A move consists of walking from one land cell to another adjacent (4-directionally that is left, right, up, and down) land cell or walking off the boundary of the grid. Find the number of land cells in the grid for which we cannot walk off the boundary of the grid in any number of moves.
Examples:
Input: grid[][] = {{0, 0, 0, 0}, {1, 0, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}}
Output: 3
Explanation: For the land cells at positions (1, 2), (2, 1) and (2, 2)
we cannot walk off the boundary.Input:
grid [][]= {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}};
Output: 0
BFS WAY :
The Approach: here we use bfs to find the result of problem the approach in following the steps :
- we need to have a visited 2d vector to initialize with 0.
- then find all boundary conditions having one in given grid just mark them visited (all the connected positions to boundary having 1 will mark visited ).
- just count all the ones in grid that are not visited that will be your answer.
#include <bits/stdc++.h> #include <iostream> using namespace std;
// global declaration. int n;
// check function for checking the current index of row and // col are within the bound or not. bool check( int row, int col)
{ return row >= 0 && col >= 0 && row < n && col < n;
} // checking the boundary condition. bool boundary( int row, int col)
{ return (row == 0 || col == 0 || row == n - 1
|| col == n - 1);
} // bfs for marking all the boundary connected ones in grid // as visited. void bfs(vector<vector< int > >& grid,
vector<vector< bool > >& vis, int row, int col)
{ queue<pair< int , int > > pq;
pq.push({ row, col });
while (!pq.empty()) {
int row = pq.front().first;
int col = pq.front().second;
pq.pop();
vis[row][col] = 1;
// to traverse in all four direction.
int dx[4] = { 0, 1, 0, -1 };
int dy[4] = { -1, 0, 1, 0 };
for ( int i = 0; i < 4; i++) {
if (check(row + dx[i], col + dy[i])
&& !vis[row + dx[i]][col + dy[i]]
&& grid[row + dx[i]][col + dy[i]] == 1) {
pq.push({ row + dx[i], col + dy[i] });
}
}
}
} int main()
{ // given grid.
vector<vector< int > > grid{ { 0, 0, 0, 0 },
{ 1, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 } };
// size of grid.
n = grid.size();
// 2d boolean vector for marking visited.
vector<vector< bool > > vis(n, vector< bool >(n, 0));
// traversing and checking boundary condition and
// marking.
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
if (boundary(i, j) && grid[i][j] == 1) {
// bfs call for marking.
bfs(grid, vis, i, j);
}
}
}
// count.
int cnt = 0;
// checking ones in grid that are not visited and that
// will be out answer.
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
if (!vis[i][j] && grid[i][j] == 1) {
++cnt;
}
}
}
// result.
cout << cnt << endl;
return 0;
// code and approach contributed by Sanket Gode.
} |
/*package whatever //do not write package name here */ import java.util.*;
class GFG
{ // global declaration.
static int n;
// check function for checking the current index of row and
// col are within the bound or not.
static boolean check( int row, int col) {
return row >= 0 && col >= 0 && row < n && col < n;
}
// checking the boundary condition.
static boolean boundary( int row, int col) {
return (row == 0 || col == 0 || row == n - 1 || col == n - 1 );
}
// bfs for marking all the boundary connected ones in grid
// as visited.
static void bfs( int [][] grid, boolean [][] vis, int row, int col) {
Queue< int []> pq = new LinkedList<>();
pq.offer( new int [] { row, col });
while (!pq.isEmpty()) {
int [] curr = pq.poll();
int currRow = curr[ 0 ];
int currCol = curr[ 1 ];
vis[currRow][currCol] = true ;
// to traverse in all four directions.
int [] dx = { 0 , 1 , 0 , - 1 };
int [] dy = { - 1 , 0 , 1 , 0 };
for ( int i = 0 ; i < 4 ; i++) {
if (check(currRow + dx[i], currCol + dy[i])
&& !vis[currRow + dx[i]][currCol + dy[i]]
&& grid[currRow + dx[i]][currCol + dy[i]] == 1 ) {
pq.offer( new int [] { currRow + dx[i], currCol + dy[i] });
}
}
}
}
public static void main(String[] args) {
// given grid.
int [][] grid = { { 0 , 0 , 0 , 0 },
{ 1 , 0 , 1 , 0 },
{ 0 , 1 , 1 , 0 },
{ 0 , 0 , 0 , 0 } };
// size of grid.
n = grid.length;
// 2d boolean array for marking visited.
boolean [][] vis = new boolean [n][n];
// traversing and checking boundary condition and marking.
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
if (boundary(i, j) && grid[i][j] == 1 ) {
// bfs call for marking.
bfs(grid, vis, i, j);
}
}
}
// count.
int cnt = 0 ;
// checking ones in grid that are not visited and that
// will be out answer.
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
if (!vis[i][j] && grid[i][j] == 1 ) {
++cnt;
}
}
}
// result.
System.out.println(cnt);
}
} // This code is contributed by aeroabrar_31 |
from queue import Queue
# Function to check if the current index of row and col are within bounds def check(row, col):
return row > = 0 and col > = 0 and row < n and col < n
# Function to check if the current index is on the boundary def boundary(row, col):
return (row = = 0 or col = = 0 or row = = n - 1 or col = = n - 1 )
# BFS function to mark all the boundary connected ones in the grid as visited def bfs(grid, vis, row, col):
pq = Queue()
pq.put((row, col))
while not pq.empty():
row, col = pq.get()
vis[row][col] = True
# To traverse in all four directions
dx = [ 0 , 1 , 0 , - 1 ]
dy = [ - 1 , 0 , 1 , 0 ]
for i in range ( 4 ):
if (check(row + dx[i], col + dy[i]) and
not vis[row + dx[i]][col + dy[i]] and
grid[row + dx[i]][col + dy[i]] = = 1 ):
pq.put((row + dx[i], col + dy[i]))
# Given grid grid = [[ 0 , 0 , 0 , 0 ],
[ 1 , 0 , 1 , 0 ],
[ 0 , 1 , 1 , 0 ],
[ 0 , 0 , 0 , 0 ]]
# Size of the grid n = len (grid)
# 2D boolean list for marking visited vis = [[ False for _ in range (n)] for _ in range (n)]
# Traverse and check boundary condition to mark visited for i in range (n):
for j in range (n):
if boundary(i, j) and grid[i][j] = = 1 :
bfs(grid, vis, i, j)
# Count cnt = 0
# Check ones in the grid that are not visited, which will be our answer for i in range (n):
for j in range (n):
if not vis[i][j] and grid[i][j] = = 1 :
cnt + = 1
# Result print (cnt)
#This Program is Contributed by Shivam Tiwari |
using System;
using System.Collections.Generic;
class GFG
{ static int n;
// Function to check if the current index of row and col are within bounds
static bool Check( int row, int col)
{
return row >= 0 && col >= 0 && row < n && col < n;
}
// Function to check the boundary condition
static bool Boundary( int row, int col)
{
return (row == 0 || col == 0 || row == n - 1 || col == n - 1);
}
// BFS for marking all the boundary connected ones in the grid as visited
static void BFS(List<List< int >> grid, bool [][] vis, int row, int col)
{
Queue<Tuple< int , int >> pq = new Queue<Tuple< int , int >>();
pq.Enqueue( new Tuple< int , int >(row, col));
while (pq.Count > 0)
{
Tuple< int , int > front = pq.Dequeue();
int r = front.Item1;
int c = front.Item2;
vis[r] = true ;
int [] dx = { 0, 1, 0, -1 };
int [] dy = { -1, 0, 1, 0 };
for ( int i = 0; i < 4; i++)
{
if (Check(r + dx[i], c + dy[i]) && !vis[r + dx[i]]] && grid[r + dx[i]]] == 1)
{
pq.Enqueue( new Tuple< int , int >(r + dx[i], c + dy[i]));
}
}
}
}
// Main function
static void Main()
{
// Given grid
List<List< int >> grid = new List<List< int >> {
new List< int > { 0, 0, 0, 0 },
new List< int > { 1, 0, 1, 0 },
new List< int > { 0, 1, 1, 0 },
new List< int > { 0, 0, 0, 0 }
};
n = grid.Count;
bool [][] vis = new bool [n][];
for ( int i = 0; i < n; i++)
{
vis[i] = new bool [n];
}
// Traversing and checking boundary condition and marking
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
if (Boundary(i, j) && grid[i][j] == 1)
{
// BFS call for marking
BFS(grid, vis, i, j);
}
}
}
// Counting ones in the grid that are not visited, and that will be our answer
int cnt = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
if (!vis[i][j] && grid[i][j] == 1)
{
cnt++;
}
}
}
// Result
Console.WriteLine(cnt);
// This code is contributed by Shivam Tiwari
}
} |
// Function to check if the current index of row and col are // within the bounds of the grid function check(row, col, n) {
return row >= 0 && col >= 0 && row < n && col < n;
} // Function to check if the current index of row and col lies on // the boundary of the grid function boundary(row, col, n) {
return row === 0 || col === 0 || row === n - 1 || col === n - 1;
} // Function to perform breadth-first search (BFS) from the given // row and col coordinates function bfs(grid, vis, row, col) {
const queue = [[row, col]];
vis[row][col] = true ;
// Direction arrays for moving in 4 directions: up, right, down,
// left
const dx = [0, 1, 0, -1];
const dy = [-1, 0, 1, 0];
while (queue.length > 0) {
const [curRow, curCol] = queue.shift();
for (let i = 0; i < 4; i++) {
const newRow = curRow + dx[i];
const newCol = curCol + dy[i];
// Check if the new coordinates are within bounds, unvisited,
// and represent a land (value of 1)
if (check(newRow, newCol, grid.length) && !vis[newRow][newCol] &&
grid[newRow][newCol] === 1) {
// Mark the new coordinates as visited and add them to the queue
// for further exploration
queue.push([newRow, newCol]);
vis[newRow][newCol] = true ;
}
}
}
} // Function to count the number of islands in the grid function countIslands(grid) {
const n = grid.length;
// Initialize a 2D boolean array for marking visited cells
const vis = Array.from({ length: n }, () => Array(n).fill( false ));
// Traverse the grid and start BFS from the boundary connected land cells
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (boundary(i, j, n) && grid[i][j] === 1) {
bfs(grid, vis, i, j); // Perform BFS from the boundary connected land cell
}
}
}
let cnt = 0;
// Count the number of unvisited land cells (islands) in the grid
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (!vis[i][j] && grid[i][j] === 1) {
cnt++;
}
}
}
return cnt; // Return the total count of islands in the grid
} // Given grid const grid = [ [0, 0, 0, 0],
[1, 0, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]
]; // Output the result console.log(countIslands(grid)); // This Code is Contributed by Shivam Tiwari |
3
Complexity Analysis:
Time Complexity: O(n*n).
Space Complexity: O(n*n).
Approach: The problem can be solved based on the following idea:
First mark the land cells which are connected by the boundary and then count the total number of cells in the islands that are not marked.
Follow the steps below to solve the problem:
- Take a visited array of size N * N, each initialized with 0
-
Do a DFS traversal on each boundary of the matrix i.e, the first row, first column, last row, and last column.
- During the traversal, check whether there is any 1 that is attached to the boundary or not.
- If attached mark that cell in the visited array as 1 and continue the dfs for its adjacent cells.
-
Initialize a counter with zero and run a for loop on each cell of the given matrix and the visited matrix.
- If for any cell, that cell is not visited and the grid contains one then such cell will contribute to the answer and increase the counter by one.
- Print the counter value.
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to run DFS on matrix void dfs(vector<vector< int > >& grid,
vector<vector< int > >& visited, int row, int col)
{ if (row >= 0 && row < grid.size() && col >= 0
&& col < grid[0].size() && grid[row][col] == 1
&& !visited[row][col]) {
visited[row][col] = 1;
dfs(grid, visited, row + 1, col);
dfs(grid, visited, row - 1, col);
dfs(grid, visited, row, col + 1);
dfs(grid, visited, row, col - 1);
}
} // Function to find the number of cells // from which we cannot walk out of boundary int numberOfEnclaves(vector<vector< int > >& grid)
{ int n = grid.size();
int m = grid[0].size();
vector<vector< int > > visited(n, vector< int >(m, 0));
// If statement to reduce
// the no of calls for the dfs
for ( int i = 0; i < n; i++) {
// First column
if (!visited[i][0] && grid[i][0] == 1) {
dfs(grid, visited, i, 0);
}
// Last column
if (!visited[i][m - 1] && grid[i][m - 1] == 1) {
dfs(grid, visited, i, m - 1);
}
}
for ( int j = 0; j < m; j++) {
// First row
if (!visited[0][j] && grid[0][j] == 1) {
dfs(grid, visited, 0, j);
}
// Last row
if (!visited[n - 1][j] && grid[n - 1][j] == 1) {
dfs(grid, visited, n - 1, j);
}
}
int count = 0;
// Loop to count the number of cells
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
if (!visited[i][j] && grid[i][j] == 1)
count++;
}
}
// Return the total count of cells
return count;
} // Driver code int main()
{ int N = 4;
vector<vector< int > > graph(N, vector< int >(N, 0));
graph = { { 0, 0, 0, 0 },
{ 1, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 } };
// Function call
cout << numberOfEnclaves(graph);
return 0;
} |
// java implementation import java.io.*;
class GFG {
// Function to run DFS on matrix
public static void dfs( int [][] grid, int [][] visited,
int row, int col)
{
if (row >= 0 && row < grid.length && col >= 0
&& col < grid[ 0 ].length && grid[row][col] == 1
&& visited[row][col] == 0 ) {
visited[row][col] = 1 ;
dfs(grid, visited, row + 1 , col);
dfs(grid, visited, row - 1 , col);
dfs(grid, visited, row, col + 1 );
dfs(grid, visited, row, col - 1 );
}
}
// Function to find the number of cells
// from which we cannot walk out off boundary
public static int numberOfEnclaves( int [][] grid)
{
int n = grid.length;
int m = grid[ 0 ].length;
int [][] visited = new int [n][m];
// If statement to reduce
// the no of calls for the dfs
for ( int i = 0 ; i < n; i++) {
// First column
if (visited[i][ 0 ] == 0 && grid[i][ 0 ] == 1 ) {
dfs(grid, visited, i, 0 );
}
// Last column
if (visited[i][m - 1 ] == 0
&& grid[i][m - 1 ] == 1 ) {
dfs(grid, visited, i, m - 1 );
}
}
for ( int j = 0 ; j < m; j++) {
// First row
if (visited[ 0 ][j] == 0 && grid[ 0 ][j] == 1 ) {
dfs(grid, visited, 0 , j);
}
// Last row
if (visited[n - 1 ][j] == 0
&& grid[n - 1 ][j] == 1 ) {
dfs(grid, visited, n - 1 , j);
}
}
int count = 0 ;
// Loop to count the number of cells
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
if (visited[i][j] == 0 && grid[i][j] == 1 )
count++;
}
}
// Return the total count of cells
return count;
}
public static void main(String[] args)
{
int N = 4 ;
int [][] graph = { { 0 , 0 , 0 , 0 },
{ 1 , 0 , 1 , 0 },
{ 0 , 1 , 1 , 0 },
{ 0 , 0 , 0 , 0 } };
// Function call
System.out.println(numberOfEnclaves(graph));
}
} // this code is contributed by ksam24000 |
# python3 code to implement the approach # Function to run DFS on matrix def dfs(grid, visited, row, col):
if (row > = 0 and row < len (grid) and col > = 0
and col < len (grid[ 0 ]) and grid[row][col] = = 1
and ( not visited[row][col])):
visited[row][col] = 1
dfs(grid, visited, row + 1 , col)
dfs(grid, visited, row - 1 , col)
dfs(grid, visited, row, col + 1 )
dfs(grid, visited, row, col - 1 )
# Function to find the number of cells # from which we cannot walk out off boundary def numberOfEnclaves(grid):
n = len (grid)
m = len (grid[ 0 ])
visited = [[ 0 for _ in range (m)] for _ in range (n)]
# If statement to reduce
# the no of calls for the dfs
for i in range ( 0 , n):
# First column
if (( not visited[i][ 0 ]) and grid[i][ 0 ] = = 1 ):
dfs(grid, visited, i, 0 )
# Last column
if (( not visited[i][m - 1 ]) and grid[i][m - 1 ] = = 1 ):
dfs(grid, visited, i, m - 1 )
for j in range ( 0 , m):
# First row
if (( not visited[ 0 ][j]) and grid[ 0 ][j] = = 1 ):
dfs(grid, visited, 0 , j)
# Last row
if (( not visited[n - 1 ][j]) and grid[n - 1 ][j] = = 1 ):
dfs(grid, visited, n - 1 , j)
count = 0
# Loop to count the number of cells
for i in range ( 0 , n):
for j in range ( 0 , m):
if (( not visited[i][j]) and grid[i][j] = = 1 ):
count + = 1
# Return the total count of cells
return count
# Driver code if __name__ = = "__main__" :
N = 4
graph = [[ 0 for _ in range (N)] for _ in range (N)]
graph = [[ 0 , 0 , 0 , 0 ],
[ 1 , 0 , 1 , 0 ],
[ 0 , 1 , 1 , 0 ],
[ 0 , 0 , 0 , 0 ]]
# Function call
print (numberOfEnclaves(graph))
# This code is contributed by rakeshsahni
|
// C# implementation using System;
public class GFG {
// Function to run DFS on matrix
static void dfs( int [, ] grid, int [, ] visited, int row,
int col)
{
if (row >= 0 && row < grid.GetLength(0) && col >= 0
&& col < grid.GetLength(1)
&& grid[row, col] == 1
&& visited[row, col] == 0) {
visited[row, col] = 1;
dfs(grid, visited, row + 1, col);
dfs(grid, visited, row - 1, col);
dfs(grid, visited, row, col + 1);
dfs(grid, visited, row, col - 1);
}
}
// Function to find the number of cells
// from which we cannot walk out off boundary
public static int numberOfEnclaves( int [, ] grid)
{
int n = grid.GetLength(0);
int m = grid.GetLength(1);
int [, ] visited = new int [n, m];
// If statement to reduce
// the no of calls for the dfs
for ( int i = 0; i < n; i++) {
// First column
if (visited[i, 0] == 0 && grid[i, 0] == 1) {
dfs(grid, visited, i, 0);
}
// Last column
if (visited[i, m - 1] == 0
&& grid[i, m - 1] == 1) {
dfs(grid, visited, i, m - 1);
}
}
for ( int j = 0; j < m; j++) {
// First row
if (visited[0, j] == 0 && grid[0, j] == 1) {
dfs(grid, visited, 0, j);
}
// Last row
if (visited[n - 1, j] == 0
&& grid[n - 1, j] == 1) {
dfs(grid, visited, n - 1, j);
}
}
int count = 0;
// Loop to count the number of cells
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
if (visited[i, j] == 0 && grid[i, j] == 1)
count++;
}
}
// Return the total count of cells
return count;
}
static public void Main()
{
int N = 4;
int [, ] graph = new int [4, 4] { { 0, 0, 0, 0 },
{ 1, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 } };
// Function call
Console.WriteLine(numberOfEnclaves(graph));
}
} // This code is contributed by ksam24000 |
// JS code to implement the approach // make 2d array function makeArray(d1, d2) {
var arr = new Array(d1), i, l;
for (i = 0, l = d2; i < l; i++) {
arr[i] = new Array(d1);
}
return arr;
} // Function to run DFS on matrix function dfs(grid ,visited ,row ,col)
{ if (row >= 0 && row < grid.length && col >= 0
&& col < grid[0].length && grid[row][col] == 1
&& !visited[row][col]) {
visited[row][col] = 1;
dfs(grid, visited, row + 1, col);
dfs(grid, visited, row - 1, col);
dfs(grid, visited, row, col + 1);
dfs(grid, visited, row, col - 1);
}
} // Function to find the number of cells // from which we cannot walk out off boundary function numberOfEnclaves(grid)
{ let n = grid.length;
let m = grid[0].length;
let visited=makeArray(n,m);
// If statement to reduce
// the no of calls for the dfs
for (let i = 0; i < n; i++) {
// First column
if (!visited[i][0] && grid[i][0] == 1) {
dfs(grid, visited, i, 0);
}
// Last column
if (!visited[i][m - 1] && grid[i][m - 1] == 1) {
dfs(grid, visited, i, m - 1);
}
}
for (let j = 0; j < m; j++) {
// First row
if (!visited[0][j] && grid[0][j] == 1) {
dfs(grid, visited, 0, j);
}
// Last row
if (!visited[n - 1][j] && grid[n - 1][j] == 1) {
dfs(grid, visited, n - 1, j);
}
}
let count = 0;
// Loop to count the number of cells
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
if (!visited[i][j] && grid[i][j] == 1)
count++;
}
}
// Return the total count of cells
return count;
} // Driver code let N = 4;
// call function to make 2d array
let graph = makeArray(N,N);
graph = [ [ 0, 0, 0, 0 ],
[ 1, 0, 1, 0 ],
[ 0, 1, 1, 0 ],
[ 0, 0, 0, 0 ] ];
// Function call
console.log(numberOfEnclaves(graph));
// This code is contributed by ksam24000.
|
3
Time Complexity: O(N * N), As here we are using DFS on the matrix cells and traversing the whole matrix.
Auxiliary Space: O(N * N) The visited array of the same dimension as that of the given matrix