Find size of the largest region in Boolean Matrix
Consider a matrix, where each cell contains either a ‘0’ or a ‘1’, and any cell containing a 1 is called a filled cell. Two cells are said to be connected if they are adjacent to each other horizontally, vertically, or diagonally. If one or more filled cells are also connected, they form a region. find the size of the largest region.
Examples:
Input: M[][]=
{{0,0,1,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,1,0,0,0,1,0,1,0,0},
{0,1,0,0,1,1,0,0,1,1,1,0,0},
{0,1,0,0,1,1,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,1,1,1,0,0,0},
{0,0,0,0,0,0,0,1,1,0,0,0,0}}
Ouptut: 11
Explanation: shown in the figure below:
Input: M[][5] = { {0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {0, 1, 0, 0, 0}, {0, 0, 0, 0, 1}}
Output: 6
Explanation: In the following example, there are 2 regions.
One with size 1 and the other as 6. So largest region: 6
Approach: To solve the problem follow the below idea:
The idea is based on the problem of finding number of islands in Boolean 2D-matrix
Find the length of the largest region in Boolean Matrix using DFS:
Follow the given steps to solve the problem:
- A cell in the 2D matrix can be connected to at most 8 neighbors.
- So in DFS, make recursive calls for 8 neighbors of that cell.
- Keep a visited Hash-map to keep track of all visited cells.
- Also, keep track of the visited 1’s in every DFS and update the maximum size region.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define ROW 4
#define COL 5
int isSafe( int M[][COL], int row, int col,
bool visited[][COL])
{
return (row >= 0) && (row < ROW) && (col >= 0)
&& (col < COL)
&& (M[row][col] && !visited[row][col]);
}
void DFS( int M[][COL], int row, int col,
bool visited[][COL], int & count)
{
static int rowNbr[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
static int colNbr[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
visited[row][col] = true ;
for ( int k = 0; k < 8; ++k) {
if (isSafe(M, row + rowNbr[k], col + colNbr[k],
visited)) {
count++;
DFS(M, row + rowNbr[k], col + colNbr[k],
visited, count);
}
}
}
int largestRegion( int M[][COL])
{
bool visited[ROW][COL];
memset (visited, 0, sizeof (visited));
int result = INT_MIN;
for ( int i = 0; i < ROW; ++i) {
for ( int j = 0; j < COL; ++j) {
if (M[i][j] && !visited[i][j]) {
int count = 1;
DFS(M, i, j, visited, count);
result = max(result, count);
}
}
}
return result;
}
int main()
{
int M[][COL] = { { 0, 0, 1, 1, 0 },
{ 1, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1 } };
cout << largestRegion(M);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int ROW, COL, count;
static boolean isSafe( int [][] M, int row, int col,
boolean [][] visited)
{
return (
(row >= 0 ) && (row < ROW) && (col >= 0 )
&& (col < COL)
&& (M[row][col] == 1 && !visited[row][col]));
}
static void DFS( int [][] M, int row, int col,
boolean [][] visited)
{
int [] rowNbr = { - 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 };
int [] colNbr = { - 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 };
visited[row][col] = true ;
for ( int k = 0 ; k < 8 ; k++) {
if (isSafe(M, row + rowNbr[k], col + colNbr[k],
visited)) {
count++;
DFS(M, row + rowNbr[k], col + colNbr[k],
visited);
}
}
}
static int largestRegion( int [][] M)
{
boolean [][] visited = new boolean [ROW][COL];
int result = 0 ;
for ( int i = 0 ; i < ROW; i++) {
for ( int j = 0 ; j < COL; j++) {
if (M[i][j] == 1 && !visited[i][j]) {
count = 1 ;
DFS(M, i, j, visited);
result = Math.max(result, count);
}
}
}
return result;
}
public static void main(String args[])
{
int M[][] = { { 0 , 0 , 1 , 1 , 0 },
{ 1 , 0 , 1 , 1 , 0 },
{ 0 , 1 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 1 } };
ROW = 4 ;
COL = 5 ;
System.out.println(largestRegion(M));
}
}
|
Python3
def isSafe(M, row, col, visited):
global ROW, COL
return ((row > = 0 ) and (row < ROW) and
(col > = 0 ) and (col < COL) and
(M[row][col] and not visited[row][col]))
def DFS(M, row, col, visited, count):
rowNbr = [ - 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 ]
colNbr = [ - 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 ]
visited[row][col] = True
for k in range ( 8 ):
if (isSafe(M, row + rowNbr[k],
col + colNbr[k], visited)):
count[ 0 ] + = 1
DFS(M, row + rowNbr[k],
col + colNbr[k], visited, count)
def largestRegion(M):
global ROW, COL
visited = [[ 0 ] * COL for i in range (ROW)]
result = - 999999999999
for i in range (ROW):
for j in range (COL):
if (M[i][j] and not visited[i][j]):
count = [ 1 ]
DFS(M, i, j, visited, count)
result = max (result, count[ 0 ])
return result
if __name__ = = '__main__' :
ROW = 4
COL = 5
M = [[ 0 , 0 , 1 , 1 , 0 ],
[ 1 , 0 , 1 , 1 , 0 ],
[ 0 , 1 , 0 , 0 , 0 ],
[ 0 , 0 , 0 , 0 , 1 ]]
print (largestRegion(M))
|
C#
using System;
class GFG {
static int ROW, COL, count;
static Boolean isSafe( int [, ] M, int row, int col,
Boolean[, ] visited)
{
return (
(row >= 0) && (row < ROW) && (col >= 0)
&& (col < COL)
&& (M[row, col] == 1 && !visited[row, col]));
}
static void DFS( int [, ] M, int row, int col,
Boolean[, ] visited)
{
int [] rowNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
int [] colNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };
visited[row, col] = true ;
for ( int k = 0; k < 8; k++) {
if (isSafe(M, row + rowNbr[k], col + colNbr[k],
visited)) {
count++;
DFS(M, row + rowNbr[k], col + colNbr[k],
visited);
}
}
}
static int largestRegion( int [, ] M)
{
Boolean[, ] visited = new Boolean[ROW, COL];
int result = 0;
for ( int i = 0; i < ROW; i++) {
for ( int j = 0; j < COL; j++) {
if (M[i, j] == 1 && !visited[i, j]) {
count = 1;
DFS(M, i, j, visited);
result = Math.Max(result, count);
}
}
}
return result;
}
public static void Main(String[] args)
{
int [, ] M = { { 0, 0, 1, 1, 0 },
{ 1, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1 } };
ROW = 4;
COL = 5;
Console.WriteLine(largestRegion(M));
}
}
|
Javascript
<script>
let ROW, COL, count;
function isSafe(M,row,col,visited)
{
return (
(row >= 0) && (row < ROW) && (col >= 0)
&& (col < COL)
&& (M[row][col] == 1 && !visited[row][col]));
}
function DFS(M,row,col,visited)
{
let rowNbr = [ -1, -1, -1, 0, 0, 1, 1, 1 ];
let colNbr = [ -1, 0, 1, -1, 1, -1, 0, 1 ];
visited[row][col] = true ;
for (let k = 0; k < 8; k++)
{
if (isSafe(M, row + rowNbr[k], col + colNbr[k],
visited))
{
count++;
DFS(M, row + rowNbr[k], col + colNbr[k],
visited);
}
}
}
function largestRegion(M)
{
let visited = new Array(ROW);
for (let i=0;i<ROW;i++)
{
visited[i]= new Array(COL);
for (let j=0;j<COL;j++)
{
visited[i][j]= false ;
}
}
let result = 0;
for (let i = 0; i < ROW; i++)
{
for (let j = 0; j < COL; j++)
{
if (M[i][j] == 1 && !visited[i][j])
{
count = 1;
DFS(M, i, j, visited);
result = Math.max(result, count);
}
}
}
return result;
}
let M=[[ 0, 0, 1, 1, 0 ],
[ 1, 0, 1, 1, 0 ],
[ 0, 1, 0, 0, 0 ],
[ 0, 0, 0, 0, 1 ] ];
ROW = 4;
COL = 5;
document.write(largestRegion(M));
</script>
|
Time complexity: O(ROW * COL). In the worst case, all the cells will be visited so the time complexity is O(ROW * COL).
Auxiliary Space: O(ROW * COL). To store the visited nodes O(ROW * COL) space is needed.
Find the length of the largest region in Boolean Matrix using BFS:
Follow the given steps to solve the problem:
- If the value at any particular cell is 1 then from here we need to do the BFS traversal
- Push the pair<i,j> in the queue
- Marking the value 1 to -1 so that we don’t again push the same cell again
- We will check in all 8 directions and if we encounter the cell having a value of 1 then we will push it into the queue and we will mark the cell to -1
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int largestRegion(vector<vector< int > >& grid)
{
int m = grid.size();
int n = grid[0].size();
queue<pair< int , int > > q;
int area = 0;
int ans = 0;
for ( int i = 0; i < m; i++) {
for ( int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
ans = 0;
q.push(make_pair(i, j));
grid[i][j] = -1;
while (!q.empty()) {
pair< int , int > t = q.front();
q.pop();
ans++;
int x = t.first;
int y = t.second;
if (x + 1 < m) {
if (grid[x + 1][y] == 1) {
q.push(make_pair(x + 1, y));
grid[x + 1][y] = -1;
}
}
if (x - 1 >= 0) {
if (grid[x - 1][y] == 1) {
q.push(make_pair(x - 1, y));
grid[x - 1][y] = -1;
}
}
if (y + 1 < n) {
if (grid[x][y + 1] == 1) {
q.push(make_pair(x, y + 1));
grid[x][y + 1] = -1;
}
}
if (y - 1 >= 0) {
if (grid[x][y - 1] == 1) {
q.push(make_pair(x, y - 1));
grid[x][y - 1] = -1;
}
}
if (x + 1 < m && y + 1 < n) {
if (grid[x + 1][y + 1] == 1) {
q.push(make_pair(x + 1, y + 1));
grid[x + 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y + 1 < n) {
if (grid[x - 1][y + 1] == 1) {
q.push(make_pair(x - 1, y + 1));
grid[x - 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y - 1 >= 0) {
if (grid[x - 1][y - 1] == 1) {
q.push(make_pair(x - 1, y - 1));
grid[x - 1][y - 1] = -1;
}
}
if (x + 1 < m && y - 1 >= 0) {
if (grid[x + 1][y - 1] == 1) {
q.push(make_pair(x + 1, y - 1));
grid[x + 1][y - 1] = -1;
}
}
}
area = max(ans, area);
ans = 0;
}
}
}
return area;
}
int main()
{
vector<vector< int > > M = { { 0, 0, 1, 1, 0 },
{ 1, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1 } };
cout << largestRegion(M);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
private static class Pair {
int x, y;
Pair( int x, int y)
{
this .x = x;
this .y = y;
}
}
private static int largestRegion( int M[][])
{
int m = M.length;
int n = M[ 0 ].length;
Queue<Pair> q = new LinkedList<>();
int area = 0 ;
int ans = 0 ;
for ( int i = 0 ; i < m; i++) {
for ( int j = 0 ; j < n; j++) {
if (M[i][j] == 1 ) {
ans = 0 ;
q.offer( new Pair(i, j));
M[i][j] = - 1 ;
while (!q.isEmpty()) {
Pair t = q.poll();
ans++;
int x = t.x;
int y = t.y;
if (x + 1 < m) {
if (M[x + 1 ][y] == 1 ) {
q.offer( new Pair(x + 1 , y));
M[x + 1 ][y] = - 1 ;
}
}
if (x - 1 >= 0 ) {
if (M[x - 1 ][y] == 1 ) {
q.offer( new Pair(x - 1 , y));
M[x - 1 ][y] = - 1 ;
}
}
if (y + 1 < n) {
if (M[x][y + 1 ] == 1 ) {
q.offer( new Pair(x, y + 1 ));
M[x][y + 1 ] = - 1 ;
}
}
if (y - 1 >= 0 ) {
if (M[x][y - 1 ] == 1 ) {
q.offer( new Pair(x, y - 1 ));
M[x][y - 1 ] = - 1 ;
}
}
if (x + 1 < m && y + 1 < n) {
if (M[x + 1 ][y + 1 ] == 1 ) {
q.offer(
new Pair(x + 1 , y + 1 ));
M[x + 1 ][y + 1 ] = - 1 ;
}
}
if (x - 1 >= 0 && y + 1 < n) {
if (M[x - 1 ][y + 1 ] == 1 ) {
q.offer(
new Pair(x - 1 , y + 1 ));
M[x - 1 ][y + 1 ] = - 1 ;
}
}
if (x - 1 >= 0 && y - 1 >= 0 ) {
if (M[x - 1 ][y - 1 ] == 1 ) {
q.offer(
new Pair(x - 1 , y - 1 ));
M[x - 1 ][y - 1 ] = - 1 ;
}
}
if (x + 1 < m && y - 1 >= 0 ) {
if (M[x + 1 ][y - 1 ] == 1 ) {
q.offer(
new Pair(x + 1 , y - 1 ));
M[x + 1 ][y - 1 ] = - 1 ;
}
}
}
area = Math.max(area, ans);
ans = 0 ;
}
}
}
return area;
}
public static void main(String[] args)
{
int M[][] = { { 0 , 0 , 1 , 1 , 0 },
{ 1 , 0 , 1 , 1 , 0 },
{ 0 , 1 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 1 } };
System.out.println(largestRegion(M));
}
}
|
Python3
from typing import List , Tuple
from collections import deque
def largestRegion(grid: List [ List [ int ]]) - > int :
m = len (grid)
n = len (grid[ 0 ])
q = deque()
area = 0
ans = 0
for i in range (m):
for j in range (n):
if grid[i][j] = = 1 :
ans = 0
q.append((i, j))
grid[i][j] = - 1
while len (q) > 0 :
t = q.popleft()
ans + = 1
x, y = t[ 0 ], t[ 1 ]
if x + 1 < m:
if grid[x + 1 ][y] = = 1 :
q.append((x + 1 , y))
grid[x + 1 ][y] = - 1
if x - 1 > = 0 :
if grid[x - 1 ][y] = = 1 :
q.append((x - 1 , y))
grid[x - 1 ][y] = - 1
if y + 1 < n:
if grid[x][y + 1 ] = = 1 :
q.append((x, y + 1 ))
grid[x][y + 1 ] = - 1
if y - 1 > = 0 :
if grid[x][y - 1 ] = = 1 :
q.append((x, y - 1 ))
grid[x][y - 1 ] = - 1
if x + 1 < m and y + 1 < n:
if grid[x + 1 ][y + 1 ] = = 1 :
q.append((x + 1 , y + 1 ))
grid[x + 1 ][y + 1 ] = - 1
if x - 1 > = 0 and y + 1 < n:
if grid[x - 1 ][y + 1 ] = = 1 :
q.append((x - 1 , y + 1 ))
grid[x - 1 ][y + 1 ] = - 1
if x - 1 > = 0 and y - 1 > = 0 :
if grid[x - 1 ][y - 1 ] = = 1 :
q.append((x - 1 , y - 1 ))
grid[x - 1 ][y - 1 ] = - 1
if x + 1 < m and y - 1 > = 0 :
if grid[x + 1 ][y - 1 ] = = 1 :
q.append((x + 1 , y - 1 ))
grid[x + 1 ][y - 1 ] = - 1
area = max (area, ans)
return area
def main():
grid = [
[ 0 , 0 , 1 , 1 , 0 ],
[ 1 , 0 , 1 , 1 , 0 ],
[ 0 , 1 , 0 , 0 , 0 ],
[ 0 , 0 , 0 , 0 , 1 ]
]
result = largestRegion(grid)
print (f 'Largest region of 1s has an area of {result}' )
main()
|
C#
using System;
using System.Collections.Generic;
class Program
{
public static int LargestRegion(List<List< int >> grid)
{
int m = grid.Count;
int n = grid[0].Count;
Queue<Tuple< int , int >> q = new Queue<Tuple< int , int >>();
int area = 0;
int ans = 0;
for ( int i = 0; i < m; i++)
{
for ( int j = 0; j < n; j++)
{
if (grid[i][j] == 1)
{
ans = 0;
q.Enqueue(Tuple.Create(i, j));
grid[i][j] = -1;
while (q.Count != 0)
{
Tuple< int , int > t = q.Dequeue();
ans++;
int x = t.Item1;
int y = t.Item2;
if (x + 1 < m)
{
if (grid[x + 1][y] == 1)
{
q.Enqueue(Tuple.Create(x + 1, y));
grid[x + 1][y] = -1;
}
}
if (x - 1 >= 0)
{
if (grid[x - 1][y] == 1)
{
q.Enqueue(Tuple.Create(x - 1, y));
grid[x - 1][y] = -1;
}
}
if (y + 1 < n)
{
if (grid[x][y + 1] == 1)
{
q.Enqueue(Tuple.Create(x, y + 1));
grid[x][y + 1] = -1;
}
}
if (y - 1 >= 0)
{
if (grid[x][y - 1] == 1)
{
q.Enqueue(Tuple.Create(x, y - 1));
grid[x][y - 1] = -1;
}
}
if (x + 1 < m && y + 1 < n)
{
if (grid[x + 1][y + 1] == 1)
{
q.Enqueue(Tuple.Create(x + 1, y + 1));
grid[x + 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y + 1 < n)
{
if (grid[x - 1][y + 1] == 1)
{
q.Enqueue(Tuple.Create(x - 1, y + 1));
grid[x - 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y - 1 >= 0)
{
if (grid[x - 1][y - 1] == 1)
{
q.Enqueue(Tuple.Create(x - 1, y - 1));
grid[x - 1][y - 1] = -1;
}
}
if (x + 1 < m && y - 1 >= 0)
{
if (grid[x + 1][y - 1] == 1)
{
q.Enqueue(Tuple.Create(x + 1, y - 1));
grid[x + 1][y - 1] = -1;
}
}
}
area = Math.Max(area, ans);
}
}
}
return area;
}
public static void Main()
{
List<List< int >> grid = new List<List< int >>();
grid.Add( new List< int > { 1, 1, 0, 0, 0 });
grid.Add( new List< int > { 0, 1, 1, 0, 0 });
grid.Add( new List< int > { 0, 0, 1, 0, 1 });
grid.Add( new List< int > { 1, 0, 0, 0, 1 });
grid.Add( new List< int > { 0, 1, 0, 1, 1 });
Console.WriteLine(LargestRegion(grid));
}
}
|
Javascript
class Queue {
constructor() {
this .items = Array.from(Array(), () => new Array());
}
push(element) {
return this .items.push(element);
}
pop() {
if ( this .items.length > 0) {
return this .items.shift();
}
}
front() {
return this .items[0];
}
empty() {
return this .items.length == 0;
}
}
function largestRegion(grid) {
let m = grid.length;
let n = grid[0].length;
let q = new Queue();
let area = 0;
let ans = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
ans = 0;
q.push([i, j]);
grid[i][j] = -1;
while (!q.empty()) {
t = q.front();
q.pop();
ans++;
let x = t[0];
let y = t[1];
if (x + 1 < m) {
if (grid[x + 1][y] == 1) {
q.push([x + 1, y]);
grid[x + 1][y] = -1;
}
}
if (x - 1 >= 0) {
if (grid[x - 1][y] == 1) {
q.push([x - 1, y]);
grid[x - 1][y] = -1;
}
}
if (y + 1 < n) {
if (grid[x][y + 1] == 1) {
q.push([x, y + 1]);
grid[x][y + 1] = -1;
}
}
if (y - 1 >= 0) {
if (grid[x][y - 1] == 1) {
q.push([x, y - 1]);
grid[x][y - 1] = -1;
}
}
if (x + 1 < m && y + 1 < n) {
if (grid[x + 1][y + 1] == 1) {
q.push([x + 1, y + 1]);
grid[x + 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y + 1 < n) {
if (grid[x - 1][y + 1] == 1) {
q.push([x - 1, y + 1]);
grid[x - 1][y + 1] = -1;
}
}
if (x - 1 >= 0 && y - 1 >= 0) {
if (grid[x - 1][y - 1] == 1) {
q.push([x - 1, y - 1]);
grid[x - 1][y - 1] = -1;
}
}
if (x + 1 < m && y - 1 >= 0) {
if (grid[x + 1][y - 1] == 1) {
q.push([x + 1, y - 1]);
grid[x + 1][y - 1] = -1;
}
}
}
area = Math.max(ans, area);
ans = 0;
}
}
}
return area;
}
M = [
[0, 0, 1, 1, 0],
[1, 0, 1, 1, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
];
console.log(largestRegion(M));
|
Time complexity: O(ROW * COL). In the worst case, all the cells will be visited so the time complexity is O(ROW * COL).
Auxiliary Space: O(ROW * COL). Space used by queue to apply BFS
This article is contributed by Nishant Singh.
Last Updated :
30 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...