Given a binary matrix mat[][] of size n x m, where 1 represents an active cell and 0 represents an inactive cell, count the number of groups of connected 1s that are completely surrounded by 0s.
Two 1 cells are considered connected if they share a side (up, down, left, or right).
A group is counted only if none of its cells lie on the boundary of the matrix.
There is 1 group of connected 1s that is completely surrounded by 0s and does not touch the boundary, so the answer is 1. The 1 on the boundary is not counted.
Only the cell at the center forms a valid group because it does not touch the boundary and is surrounded by 0s. The other 1s lie on the boundary of the matrix, so they are not counted.
DFS Traversal in Two Pass- O(n * m) and O(n * m) Space
First, we traverse all the boundary cells of the matrix. If a boundary cell contains 1, we perform DFS from that cell and mark all connected 1s as visited/
After marking all boundary-connected groups, we traverse the entire matrix again. For every unvisited 1, we perform DFS to explore its connected group. Each such DFS represents one group of surrounded 1s, so we increment the count.
C++
#include<iostream>#include<vector>usingnamespacestd;// DFS to mark all connected land cells as visitedvoiddfs(vector<vector<int>>&matrix,vector<vector<bool>>&visited,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;visited[x][y]=true;// Traverse to all adjacent elementsdfs(matrix,visited,x+1,y,n,m);dfs(matrix,visited,x-1,y,n,m);dfs(matrix,visited,x,y+1,n,m);dfs(matrix,visited,x,y-1,n,m);}// Count the groups of surrounded 1sintcountGroups(vector<vector<int>>&matrix){intn=matrix.size(),m=matrix[0].size();vector<vector<bool>>visited(n,vector<bool>(m,false));// Mark groups connected to the boundaryfor(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is boundary and not visitedif((i*j==0||i==n-1||j==m-1)&&matrix[i][j]==1&&!visited[i][j]){dfs(matrix,visited,i,j,n,m);}}}intres=0;// Count remaining unvisited groups of surrounded 1sfor(inti=0;i<n;++i){for(intj=0;j<m;++j){if(matrix[i][j]==1&&!visited[i][j]){res++;dfs(matrix,visited,i,j,n,m);}}}returnres;}intmain(){vector<vector<int>>matrix={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};cout<<countGroups(matrix);return0;}
Java
importjava.util.Arrays;publicclassGFG{// DFS to mark all connected land cells as visitedpublicstaticvoiddfs(int[][]matrix,boolean[][]visited,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;visited[x][y]=true;// Traverse to all adjacent elementsdfs(matrix,visited,x+1,y,n,m);dfs(matrix,visited,x-1,y,n,m);dfs(matrix,visited,x,y+1,n,m);dfs(matrix,visited,x,y-1,n,m);}// Count the groups of surrounded 1spublicstaticintcountGroups(int[][]matrix){intn=matrix.length,m=matrix[0].length;boolean[][]visited=newboolean[n][m];// Mark groups connected to the boundaryfor(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is boundary and not visitedif((i*j==0||i==n-1||j==m-1)&&matrix[i][j]==1&&!visited[i][j]){dfs(matrix,visited,i,j,n,m);}}}intres=0;// Count remaining unvisited groups of surrounded 1sfor(inti=0;i<n;++i){for(intj=0;j<m;++j){if(matrix[i][j]==1&&!visited[i][j]){res++;dfs(matrix,visited,i,j,n,m);}}}returnres;}publicstaticvoidmain(String[]args){int[][]matrix={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};System.out.println(countGroups(matrix));}}
Python
defdfs(matrix,visited,x,y,n,m):ifx<0ory<0orx>=nory>=morvisited[x][y]ormatrix[x][y]==0:returnvisited[x][y]=True# Traverse to all adjacent elementsdfs(matrix,visited,x+1,y,n,m)dfs(matrix,visited,x-1,y,n,m)dfs(matrix,visited,x,y+1,n,m)dfs(matrix,visited,x,y-1,n,m)defcountGroups(matrix):n=len(matrix)m=len(matrix[0])visited=[[Falsefor_inrange(m)]for_inrange(n)]# Mark groups connected to the boundaryforiinrange(n):forjinrange(m):# Check it is boundary and not visitedif(i*j==0ori==n-1orj==m-1)andmatrix[i][j]==1andnotvisited[i][j]:dfs(matrix,visited,i,j,n,m)res=0# Count remaining unvisited groups of surrounded 1sforiinrange(n):forjinrange(m):ifmatrix[i][j]==1andnotvisited[i][j]:res+=1dfs(matrix,visited,i,j,n,m)returnresif__name__=="__main__":matrix=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]]print(countGroups(matrix))
C#
usingSystem;classGFG{// DFS to mark all connected 1s as visitedstaticvoidDfs(int[][]matrix,bool[][]visited,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;visited[x][y]=true;// Traverse to all adjacent elementsDfs(matrix,visited,x+1,y,n,m);Dfs(matrix,visited,x-1,y,n,m);Dfs(matrix,visited,x,y+1,n,m);Dfs(matrix,visited,x,y-1,n,m);}// Count the groups of surrounded 1sstaticintcountGroups(int[][]matrix){intn=matrix.Length;intm=matrix[0].Length;bool[][]visited=newbool[n][];for(inti=0;i<n;i++)visited[i]=newbool[m];// Mark groups connected to the boundaryfor(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is boundary and not visitedif((i==0||j==0||i==n-1||j==m-1)&&matrix[i][j]==1&&!visited[i][j]){Dfs(matrix,visited,i,j,n,m);}}}intres=0;// Count remaining unvisited groups of surrounded 1sfor(inti=0;i<n;++i){for(intj=0;j<m;++j){if(matrix[i][j]==1&&!visited[i][j]){res++;Dfs(matrix,visited,i,j,n,m);}}}returnres;}staticintMain(){int[][]matrix=newint[][]{newint[]{0,0,0,0,0},newint[]{0,1,0,1,0},newint[]{0,1,1,1,0},newint[]{0,0,0,0,1}};Console.WriteLine(countGroups(matrix));return0;}}
JavaScript
functiondfs(matrix,visited,x,y,n,m){if(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]===0)return;visited[x][y]=true;// Traverse to all adjacent elementsdfs(matrix,visited,x+1,y,n,m);dfs(matrix,visited,x-1,y,n,m);dfs(matrix,visited,x,y+1,n,m);dfs(matrix,visited,x,y-1,n,m);}functioncountGroups(matrix){letn=matrix.length,m=matrix[0].length;letvisited=Array.from({length:n},()=>Array(m).fill(false));// Mark groups connected to the boundaryfor(leti=0;i<n;++i){for(letj=0;j<m;++j){// Check it is boundary and not visitedif((i*j===0||i===n-1||j===m-1)&&matrix[i][j]===1&&!visited[i][j]){dfs(matrix,visited,i,j,n,m);}}}letres=0;// Count remaining unvisited groups of surrounded 1sfor(leti=0;i<n;++i){for(letj=0;j<m;++j){if(matrix[i][j]===1&&!visited[i][j]){res++;dfs(matrix,visited,i,j,n,m);}}}returnres;}// Driver Codeletmatrix=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]];console.log(countGroups(matrix));
Output
1
DFS Traversal in One Pass – O(n * m) Time and O(n * m) Space
Instead of performing two separate DFS traversals, we perform a single DFS from each unvisited 1 cell. We maintain a boolean variable hasBoundary to track whether the current group of 1s touches the boundary.
During DFS, if any 1 cell lies on the boundary, we set hasBoundary to true. After the DFS completes, if hasBoundary is false, the group does not touch the boundary, so we count it as a group of surrounded 1s.
C++
#include<iostream>#include<vector>usingnamespacestd;// DFS to mark all connected land cells as visitedvoiddfs(vector<vector<int>>&matrix,vector<vector<bool>>&visited,intx,inty,intn,intm,bool&hasBoundary){// Base caseif(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;// Mark if the current land cell lies on the boundaryif(x==0||y==0||x==n-1||y==m-1)hasBoundary=true;visited[x][y]=true;// Explore all 4 directionsdfs(matrix,visited,x+1,y,n,m,hasBoundary);dfs(matrix,visited,x-1,y,n,m,hasBoundary);dfs(matrix,visited,x,y+1,n,m,hasBoundary);dfs(matrix,visited,x,y-1,n,m,hasBoundary);}// Count the groups of surrounded 1sintcountGroups(vector<vector<int>>&matrix){intn=matrix.size(),m=matrix[0].size();vector<vector<bool>>visited(n,vector<bool>(m,false));intres=0;// Start DFS for land cellsfor(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is land cell and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolhasBoundary=false;dfs(matrix,visited,i,j,n,m,hasBoundary);// Count only if not touching boundaryif(!hasBoundary)res++;}}}returnres;}intmain(){vector<vector<int>>matrix={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};cout<<countGroups(matrix);return0;}
Java
importjava.util.Arrays;publicclassGFG{// DFS to mark all connected land cells as visitedpublicstaticvoiddfs(int[][]matrix,boolean[][]visited,intx,inty,intn,intm,boolean[]hasBoundary){// Base caseif(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;// Mark if the current land cell lies on the// boundaryif(x==0||y==0||x==n-1||y==m-1)hasBoundary[0]=true;visited[x][y]=true;// Explore all 4 directionsdfs(matrix,visited,x+1,y,n,m,hasBoundary);dfs(matrix,visited,x-1,y,n,m,hasBoundary);dfs(matrix,visited,x,y+1,n,m,hasBoundary);dfs(matrix,visited,x,y-1,n,m,hasBoundary);}// Count the groups of surrounded 1spublicstaticintcountGroups(int[][]matrix){intn=matrix.length,m=matrix[0].length;boolean[][]visited=newboolean[n][m];intres=0;// Start DFS for land cellsfor(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is land cell and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolean[]hasBoundary={false};dfs(matrix,visited,i,j,n,m,hasBoundary);// Count only if not touching boundaryif(!hasBoundary[0])res++;}}}returnres;}publicstaticvoidmain(String[]args){int[][]matrix={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};System.out.println(countGroups(matrix));}}
Python
defdfs(matrix,visited,x,y,n,m,hasBoundary):# Base caseifx<0ory<0orx>=nory>=morvisited[x][y]ormatrix[x][y]==0:return# Mark if the current land cell lies on the boundaryifx==0ory==0orx==n-1ory==m-1:hasBoundary[0]=Truevisited[x][y]=True# Explore all 4 directionsdfs(matrix,visited,x+1,y,n,m,hasBoundary)dfs(matrix,visited,x-1,y,n,m,hasBoundary)dfs(matrix,visited,x,y+1,n,m,hasBoundary)dfs(matrix,visited,x,y-1,n,m,hasBoundary)defcountGroups(matrix):n=len(matrix)m=len(matrix[0])visited=[[False]*mfor_inrange(n)]res=0# Start DFS for land cellsforiinrange(n):forjinrange(m):# Check it is land cell and not visitedifmatrix[i][j]==1andnotvisited[i][j]:hasBoundary=[False]dfs(matrix,visited,i,j,n,m,hasBoundary)# Count only if not touching boundaryifnothasBoundary[0]:res+=1returnresif__name__=='__main__':matrix=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]]print(countGroups(matrix))
C#
usingSystem;publicclassGFG{// DFS to mark all connected 1s as visitedpublicstaticvoiddfs(int[][]matrix,bool[][]visited,intx,inty,intn,intm,refboolhasBoundary){// Base caseif(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]==0)return;// Mark if the current 1 lies on the boundaryif(x==0||y==0||x==n-1||y==m-1)hasBoundary=true;visited[x][y]=true;// Explore all 4 directionsdfs(matrix,visited,x+1,y,n,m,refhasBoundary);dfs(matrix,visited,x-1,y,n,m,refhasBoundary);dfs(matrix,visited,x,y+1,n,m,refhasBoundary);dfs(matrix,visited,x,y-1,n,m,refhasBoundary);}// Count the groups of surrounded 1spublicstaticintcountGroups(int[][]matrix){intn=matrix.Length;intm=matrix[0].Length;bool[][]visited=newbool[n][];for(inti=0;i<n;i++)visited[i]=newbool[m];intres=0;// Start DFS for each unvisited 1for(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check it is a 1 and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolhasBoundary=false;dfs(matrix,visited,i,j,n,m,refhasBoundary);// Count only if not touching boundaryif(!hasBoundary)res++;}}}returnres;}publicstaticintMain(){int[][]matrix=newint[][]{newint[]{0,0,0,0,0},newint[]{0,1,0,1,0},newint[]{0,1,1,1,0},newint[]{0,0,0,0,1}};Console.WriteLine(countGroups(matrix));return0;}}
JavaScript
functiondfs(matrix,visited,x,y,n,m,hasBoundary){// Base caseif(x<0||y<0||x>=n||y>=m||visited[x][y]||matrix[x][y]===0)return;// Mark if the current land cell lies on the boundaryif(x===0||y===0||x===n-1||y===m-1)hasBoundary[0]=true;visited[x][y]=true;// Explore all 4 directionsdfs(matrix,visited,x+1,y,n,m,hasBoundary);dfs(matrix,visited,x-1,y,n,m,hasBoundary);dfs(matrix,visited,x,y+1,n,m,hasBoundary);dfs(matrix,visited,x,y-1,n,m,hasBoundary);}functioncountGroups(matrix){constn=matrix.length;constm=matrix[0].length;constvisited=Array.from({length:n},()=>Array(m).fill(false));letres=0;// Start DFS for land cellsfor(leti=0;i<n;++i){for(letj=0;j<m;++j){// Check it is land cell and not visitedif(matrix[i][j]===1&&!visited[i][j]){consthasBoundary=[false];dfs(matrix,visited,i,j,n,m,hasBoundary);// Count only if not touching boundaryif(!hasBoundary[0])res++;}}}returnres;}// Driver Codeconstmatrix=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]];console.log(countGroups(matrix));
Output
1
BFS Traversal – O(n * m) Time and O(n * m) Space
The idea is similar to the DFS-based approach, but here we use Breadth-First Search (BFS) instead of DFS to count the number of groups of surrounded 1s.
C++
#include<iostream>#include<queue>#include<vector>usingnamespacestd;// BFS to mark all connected 1s as visitedvoiddfs(vector<vector<int>>&matrix,vector<vector<bool>>&visited,intx,inty,intn,intm,bool&hasBoundary){queue<pair<int,int>>q;q.push({x,y});visited[x][y]=true;// Directions: down, up, right, leftintdx[]={1,-1,0,0};intdy[]={0,0,1,-1};while(!q.empty()){auto[cx,cy]=q.front();q.pop();// Check if the current 1 lies on the boundaryif(cx==0||cy==0||cx==n-1||cy==m-1)hasBoundary=true;// Explore all four adjacent cellsfor(intdir=0;dir<4;++dir){intnx=cx+dx[dir];intny=cy+dy[dir];// Check valid, unvisited, and connected 1if(nx>=0&&ny>=0&&nx<n&&ny<m&&!visited[nx][ny]&&matrix[nx][ny]==1){visited[nx][ny]=true;q.push({nx,ny});}}}}// Count the groups of surrounded 1sintcountGroups(vector<vector<int>>&matrix){intn=matrix.size(),m=matrix[0].size();vector<vector<bool>>visited(n,vector<bool>(m,false));intres=0;// Start BFS for each unvisited 1for(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check if the cell is a 1 and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolhasBoundary=false;dfs(matrix,visited,i,j,n,m,hasBoundary);// Count only groups that do not touch the boundaryif(!hasBoundary)res++;}}}returnres;}intmain(){vector<vector<int>>mat={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};cout<<countGroups(mat);return0;}
Java
importjava.util.LinkedList;importjava.util.Queue;classGFG{// BFS to mark all connected 1s as visitedstaticvoiddfs(int[][]matrix,boolean[][]visited,intx,inty,intn,intm,boolean[]hasBoundary){Queue<int[]>q=newLinkedList<>();q.add(newint[]{x,y});visited[x][y]=true;// Directions: down, up, right, leftint[]dx={1,-1,0,0};int[]dy={0,0,1,-1};while(!q.isEmpty()){int[]cur=q.poll();intcx=cur[0];intcy=cur[1];// Check if the current 1 lies on the boundaryif(cx==0||cy==0||cx==n-1||cy==m-1)hasBoundary[0]=true;// Explore all four adjacent cellsfor(intdir=0;dir<4;++dir){intnx=cx+dx[dir];intny=cy+dy[dir];// Check valid, unvisited, and connected 1if(nx>=0&&ny>=0&&nx<n&&ny<m&&!visited[nx][ny]&&matrix[nx][ny]==1){visited[nx][ny]=true;q.add(newint[]{nx,ny});}}}}// Count the groups of surrounded 1sstaticintcountGroups(int[][]matrix){intn=matrix.length,m=matrix[0].length;boolean[][]visited=newboolean[n][m];intres=0;// Start BFS for each unvisited 1for(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check if the cell is a 1 and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolean[]hasBoundary={false};dfs(matrix,visited,i,j,n,m,hasBoundary);// Count only groups that do not touch// the boundaryif(!hasBoundary[0])res++;}}}returnres;}publicstaticvoidmain(String[]args){int[][]mat={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};System.out.println(countGroups(mat));}}
Python
fromcollectionsimportdeque# BFS to mark all connected 1s as visiteddefdfs(matrix,visited,x,y,n,m,hasBoundary):q=deque([(x,y)])visited[x][y]=True# Directions: down, up, right, leftdx=[1,-1,0,0]dy=[0,0,1,-1]whileq:cx,cy=q.popleft()# Check if the current 1 lies on the boundaryifcx==0orcy==0orcx==n-1orcy==m-1:hasBoundary[0]=True# Explore all four adjacent cellsfordirinrange(4):nx=cx+dx[dir]ny=cy+dy[dir]# Check valid, unvisited, and connected 1if0<=nx<nand0<=ny<mandnotvisited[nx][ny]andmatrix[nx][ny]==1:visited[nx][ny]=Trueq.append((nx,ny))# Count the groups of surrounded 1sdefcountGroups(matrix):n=len(matrix)m=len(matrix[0])visited=[[False]*mfor_inrange(n)]res=0# Start BFS for each unvisited 1foriinrange(n):forjinrange(m):# Check if the cell is a 1 and not visitedifmatrix[i][j]==1andnotvisited[i][j]:hasBoundary=[False]dfs(matrix,visited,i,j,n,m,hasBoundary)# Count only groups that do not touch the boundaryifnothasBoundary[0]:res+=1returnresif__name__=='__main__':mat=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]]print(countGroups(mat))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// BFS to mark all connected 1s as visitedstaticvoiddfs(int[][]matrix,bool[][]visited,intx,inty,intn,intm,refboolhasBoundary){Queue<(int,int)>q=newQueue<(int,int)>();q.Enqueue((x,y));visited[x][y]=true;// Directions: down, up, right, leftint[]dx={1,-1,0,0};int[]dy={0,0,1,-1};while(q.Count>0){var(cx,cy)=q.Dequeue();// Check if the current 1 lies on the boundaryif(cx==0||cy==0||cx==n-1||cy==m-1)hasBoundary=true;// Explore all four adjacent cellsfor(intdir=0;dir<4;++dir){intnx=cx+dx[dir];intny=cy+dy[dir];// Check valid, unvisited, and connected 1if(nx>=0&&ny>=0&&nx<n&&ny<m&&!visited[nx][ny]&&matrix[nx][ny]==1){visited[nx][ny]=true;q.Enqueue((nx,ny));}}}}// Count the groups of surrounded 1sstaticintcountGroups(int[][]matrix){intn=matrix.Length,m=matrix[0].Length;bool[][]visited=newbool[n][];for(inti=0;i<n;++i)visited[i]=newbool[m];intres=0;// Start BFS for each unvisited 1for(inti=0;i<n;++i){for(intj=0;j<m;++j){// Check if the cell is a 1 and not visitedif(matrix[i][j]==1&&!visited[i][j]){boolhasBoundary=false;dfs(matrix,visited,i,j,n,m,refhasBoundary);// Count only groups that do not touch// the boundaryif(!hasBoundary)res++;}}}returnres;}staticvoidMain(string[]args){int[][]mat=newint[][]{newint[]{0,0,0,0,0},newint[]{0,1,0,1,0},newint[]{0,1,1,1,0},newint[]{0,0,0,0,1}};Console.WriteLine(countGroups(mat));}}
JavaScript
// BFS to mark all connected 1s as visitedfunctionbfs(matrix,visited,x,y,n,m,hasBoundary){letq=[[x,y]];visited[x][y]=true;// Directions: down, up, right, leftletdx=[1,-1,0,0];letdy=[0,0,1,-1];while(q.length>0){let[cx,cy]=q.shift();// Check if the current 1 lies on the boundaryif(cx===0||cy===0||cx===n-1||cy===m-1)hasBoundary.value=true;// Explore all four adjacent cellsfor(letdir=0;dir<4;dir++){letnx=cx+dx[dir];letny=cy+dy[dir];// Check valid, unvisited, and connected 1if(nx>=0&&ny>=0&&nx<n&&ny<m&&!visited[nx][ny]&&matrix[nx][ny]===1){visited[nx][ny]=true;q.push([nx,ny]);}}}}// Count the groups of surrounded 1sfunctioncountGroups(matrix){letn=matrix.length;letm=matrix[0].length;letvisited=Array.from({length:n},()=>Array(m).fill(false));letres=0;// Start BFS for each unvisited 1for(leti=0;i<n;i++){for(letj=0;j<m;j++){// Check if the cell is a 1 and not visitedif(matrix[i][j]===1&&!visited[i][j]){lethasBoundary={value:false};bfs(matrix,visited,i,j,n,m,hasBoundary);// Count only groups that do not touch the// boundaryif(!hasBoundary.value)res++;}}}returnres;}// Driver codeletmat=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]];console.log(countGroups(mat));
Output
1
Disjoint-Set ( Union-Find ) – O(n * m) Time and O(n * m) Space
The main idea is to use the Disjoint Set Union (DSU). Each 1 cell is treated as a node, and adjacent 1 cells are joined into the same set using union operations.
First, groups of 1s connected to the boundary are removed, since they cannot be completely surrounded by 0s.
After processing the remaining cells, the number of distinct sets gives the total number of groups of surrounded 1s.
C++
#include<iostream>#include<numeric>#include<vector>usingnamespacestd;vector<int>parent;// Find the root of a nodeintfind(intx){if(parent[x]==x)returnx;returnparent[x]=find(parent[x]);}// Union two setsvoidunionFind(inta,intb){introotA=find(a);introotB=find(b);if(rootA!=rootB)parent[rootA]=rootB;}// DFS to mark all boundary-connected land cells as watervoidfloodFill(vector<vector<int>>&mat,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||mat[x][y]==0)return;// Mark as watermat[x][y]=0;floodFill(mat,x+1,y,n,m);floodFill(mat,x-1,y,n,m);floodFill(mat,x,y+1,n,m);floodFill(mat,x,y-1,n,m);}// Remove all land connected to the boundaryvoidremBoundIs(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Check boundary cellsif(i==0||j==0||i==n-1||j==m-1){if(mat[i][j]==1)floodFill(mat,i,j,n,m);}}}}// Count the groups of surrounded 1sintcountGroups(vector<vector<int>>&mat){if(mat.empty())return0;intn=mat.size();intm=mat[0].size();// Remove groups connected to boundaryremBoundIs(mat);// Initialize DSUparent.resize(n*m);iota(parent.begin(),parent.end(),0);// Connect adjacent 1sfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;// Connect to right neighborif(j+1<m&&mat[i][j+1]==1)unionFind(id,id+1);// Connect to bottom neighborif(i+1<n&&mat[i+1][j]==1)unionFind(id,id+m);}}}// Count distinct groupsintcount=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;if(find(id)==id)count++;}}}returncount;}intmain(){vector<vector<int>>mat={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};cout<<countGroups(mat);return0;}
Java
importjava.util.Arrays;publicclassGFG{staticint[]parent;// Find the root of a nodestaticintfind(intx){if(parent[x]==x)returnx;returnparent[x]=find(parent[x]);}// Union two setsstaticvoidunionFind(inta,intb){introotA=find(a);introotB=find(b);if(rootA!=rootB)parent[rootA]=rootB;}// DFS to mark all boundary-connected land cells as// waterstaticvoidfloodFill(int[][]mat,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||mat[x][y]==0)return;// Mark as watermat[x][y]=0;floodFill(mat,x+1,y,n,m);floodFill(mat,x-1,y,n,m);floodFill(mat,x,y+1,n,m);floodFill(mat,x,y-1,n,m);}// Remove all land connected to the boundarystaticvoidremBoundIs(int[][]mat){intn=mat.length;intm=mat[0].length;for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Check boundary cellsif(i==0||j==0||i==n-1||j==m-1){if(mat[i][j]==1)floodFill(mat,i,j,n,m);}}}}// Count the groups of surrounded 1sstaticintcountGroups(int[][]mat){if(mat.length==0)return0;intn=mat.length;intm=mat[0].length;// Remove groups connected to boundaryremBoundIs(mat);// Initialize DSUparent=newint[n*m];for(inti=0;i<n*m;i++){parent[i]=i;}// Connect adjacent 1sfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;// Connect to right neighborif(j+1<m&&mat[i][j+1]==1)unionFind(id,id+1);// Connect to bottom neighborif(i+1<n&&mat[i+1][j]==1)unionFind(id,id+m);}}}// Count distinct groupsintcount=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;if(find(id)==id)count++;}}}returncount;}publicstaticvoidmain(String[]args){int[][]mat={{0,0,0,0,0},{0,1,0,1,0},{0,1,1,1,0},{0,0,0,0,1}};System.out.println(countGroups(mat));}}
Python
fromtypingimportListparent=[]# Find the root of a nodedeffind(x):ifparent[x]==x:returnxparent[x]=find(parent[x])returnparent[x]# Union two setsdefunionFind(a,b):rootA=find(a)rootB=find(b)ifrootA!=rootB:parent[rootA]=rootB# DFS to mark all boundary-connected 1s as 0deffloodFill(mat,x,y,n,m):ifx<0ory<0orx>=nory>=mormat[x][y]==0:returnmat[x][y]=0floodFill(mat,x+1,y,n,m)floodFill(mat,x-1,y,n,m)floodFill(mat,x,y+1,n,m)floodFill(mat,x,y-1,n,m)# Remove all 1s connected to the boundarydefremBoundIs(mat):n=len(mat)m=len(mat[0])foriinrange(n):forjinrange(m):ifi==0orj==0ori==n-1orj==m-1:ifmat[i][j]==1:floodFill(mat,i,j,n,m)# Count the groups of surrounded 1sdefcountGroups(mat:List[List[int]])->int:globalparentifnotmat:return0n=len(mat)m=len(mat[0])# Remove groups connected to the boundaryremBoundIs(mat)# Initialize DSUparent=list(range(n*m))# Connect adjacent 1sforiinrange(n):forjinrange(m):ifmat[i][j]==1:id=i*m+j# Connect to right neighborifj+1<mandmat[i][j+1]==1:unionFind(id,id+1)# Connect to bottom neighborifi+1<nandmat[i+1][j]==1:unionFind(id,id+m)# Count distinct groupscount=0foriinrange(n):forjinrange(m):ifmat[i][j]==1:id=i*m+jiffind(id)==id:count+=1returncountif__name__=='__main__':mat=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]]print(countGroups(mat))
C#
usingSystem;classGFG{staticint[]parent;// Find the root of a nodestaticintFind(intx){if(parent[x]==x)returnx;returnparent[x]=Find(parent[x]);}// Union two setsstaticvoidUnionFind(inta,intb){introotA=Find(a);introotB=Find(b);if(rootA!=rootB)parent[rootA]=rootB;}// DFS to mark all boundary-connected 1sstaticvoidFloodFill(int[][]mat,intx,inty,intn,intm){if(x<0||y<0||x>=n||y>=m||mat[x][y]==0)return;// Mark as 0mat[x][y]=0;FloodFill(mat,x+1,y,n,m);FloodFill(mat,x-1,y,n,m);FloodFill(mat,x,y+1,n,m);FloodFill(mat,x,y-1,n,m);}// Remove all 1s connected to the boundarystaticvoidRemoveBoundaryGroups(int[][]mat){intn=mat.Length;intm=mat[0].Length;for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Check boundary cellsif(i==0||j==0||i==n-1||j==m-1){if(mat[i][j]==1)FloodFill(mat,i,j,n,m);}}}}// Count the groups of surrounded 1sstaticintcountGroups(int[][]mat){if(mat==null||mat.Length==0)return0;intn=mat.Length;intm=mat[0].Length;// Remove groups connected to boundaryRemoveBoundaryGroups(mat);// Initialize DSUparent=newint[n*m];for(inti=0;i<n*m;i++)parent[i]=i;// Connect adjacent 1sfor(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;// Connect to right neighborif(j+1<m&&mat[i][j+1]==1)UnionFind(id,id+1);// Connect to bottom neighborif(i+1<n&&mat[i+1][j]==1)UnionFind(id,id+m);}}}// Count distinct groupsintcount=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==1){intid=i*m+j;if(Find(id)==id)count++;}}}returncount;}publicstaticintMain(){int[][]mat={newint[]{0,0,0,0,0},newint[]{0,1,0,1,0},newint[]{0,1,1,1,0},newint[]{0,0,0,0,1}};Console.WriteLine(countGroups(mat));return0;}}
JavaScript
letparent=[];// Find the root of a nodefunctionfind(x){if(parent[x]===x)returnx;returnparent[x]=find(parent[x]);}// Union two setsfunctionunionFind(a,b){letrootA=find(a);letrootB=find(b);if(rootA!==rootB)parent[rootA]=rootB;}// DFS to mark all boundary-connected land cells as waterfunctionfloodFill(mat,x,y,n,m){if(x<0||y<0||x>=n||y>=m||mat[x][y]===0)return;// Mark as watermat[x][y]=0;floodFill(mat,x+1,y,n,m);floodFill(mat,x-1,y,n,m);floodFill(mat,x,y+1,n,m);floodFill(mat,x,y-1,n,m);}// Remove all land connected to the boundaryfunctionremBoundIs(mat){letn=mat.length;letm=mat[0].length;for(leti=0;i<n;i++){for(letj=0;j<m;j++){// Check boundary cellsif(i===0||j===0||i===n-1||j===m-1){if(mat[i][j]===1)floodFill(mat,i,j,n,m);}}}}// Count the groups of surrounded 1sfunctioncountGroups(mat){if(mat.length===0)return0;letn=mat.length;letm=mat[0].length;// Remove groups connected to boundaryremBoundIs(mat);// Initialize DSUparent=newArray(n*m).fill().map((_,index)=>index);// Connect adjacent 1sfor(leti=0;i<n;i++){for(letj=0;j<m;j++){if(mat[i][j]===1){letid=i*m+j;// Connect to right neighborif(j+1<m&&mat[i][j+1]===1)unionFind(id,id+1);// Connect to bottom neighborif(i+1<n&&mat[i+1][j]===1)unionFind(id,id+m);}}}// Count distinct groupsletcount=0;for(leti=0;i<n;i++){for(letj=0;j<m;j++){if(mat[i][j]===1){letid=i*m+j;if(find(id)===id)count++;}}}returncount;}// Driver Codeletmat=[[0,0,0,0,0],[0,1,0,1,0],[0,1,1,1,0],[0,0,0,0,1]];console.log(countGroups(mat));