Open In App

Number of land cells for which we cannot walk off the boundary of Grid

Last Updated : 21 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.

C++




#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.
}


Java




/*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


Python3




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


C#




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
    }
}


Javascript




// 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


Output

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++




// 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




// 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




# 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#




// 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


Javascript




// 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.


Output

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads