
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Size of All Connected Non-Empty Cells of a Matrix
In this problem, we will find the size of sets of all non?empty connected cells.
We will learn two different approaches for finding the size of all non?empty connected cells of a matrix. In the first approach, we will use the breadth?first search algorithm, and in the second approach, we will use the depth?first search algorithm to traverse the matrix and find the size of all non-empty connected cells.
Problem statement ? We have given matrix[][] 2D array containing only 0 and 1. Here, 0 represents the empty cell, and 1 represents the non?empty cells. We need to find the size of the non?empty connected cells.
Note ? We can say that two cells are connected if they are horizontally and vertically adjacent to each other.
Sample examples
Input
{{0, 1, 0, 0, 0}, {0, 1, 1, 1, 1}, {1, 0, 0, 1, 1}, {1, 0, 0, 0, 0}, {0, 0, 1, 1, 1}};
Output
7 2 3
Explanation
The first connected set contains matrix[0][1], matrix[1][1], matrix[1][2], matrix[1][3], matrix[1][4], matrix[2][3], and matrix[2][4] cells.
The second connected set contains the matrix[2][0], and matrix[3][0] cells.
The third connected set contains the matrix[4][2], matrix[4][3], and matrix[4][4] cells.
Input
{{0, 1, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 0, 1, 1}, {0, 0, 0, 1, 0}, {0, 0, 1, 1, 1}};
Output
11
Explanation ? All non?empty cells of the matrix are connected.
Approach 1
In this approach, we will use the BFS technique to traverse each matrix cell. If we find the non?empty cell, we start BFS traversal from that cell to find the number of all connected nodes. Also, we update the visited nodes to 0, as we don't want to calculate the same node multiple times.
Algorithm
Step 1 ? Use two nested loops to traverse the matrix.
Step 2 ? If the value of the current cell is 1, call the BFSTraversal() function to get the size of all connected cells to the current cell.
Step 2.1 ? In the BFSTraversal() function, initialize the ?res' with 0 to store the size. Also, define the queue for the BFS traversal.
Step 2.2 ? Insert the coordinates of the current cell into the queue
Step 2.3 ? Make traversal while the queue is not empty.
Step 2.3.1 ? Get the first pair from the queue inside the loop.
Step 2.3.2 ? Get the row and column values from the first pair. Also, check the boundary validation to ensure the row and column pair is a valid matrix cell.
Step 2.3.3 ? If matrix[row][col] is 0, continue with the next iteration of the loop. Otherwise, update the matrix[col][row] with 0, and increment the ?res' by 1.
Step 2.3.4 ? Insert the pairs of row and col for all 4 neighbor elements into the queue.
Step 2.4 ? Return the ?res' value.
Step 3 ? Insert the returned value from the BFSTraversal() function to the ?ans' list.
Step 4 ? Print all elements of the ?ans' list.
Example
#include <bits/stdc++.h> using namespace std; int BFSTraversal(vector<vector<int>> &matrix, int p, int q, int rows, int cols) { int res = 0; // Queue to store the cells queue<pair<int, int>> que; // Insert the starting point que.push({p, q}); while (!que.empty()) { // Get the first element from the queue auto first = que.front(); que.pop(); int row = first.first, col = first.second; // Boundry validation if (row < 0 || col < 0 || row > rows - 1 || col > cols - 1) continue; // For visited elements if (matrix[row][col] == 0) continue; // For non-visited elements if (matrix[row][col] == 1) { // Update matrix cell matrix[row][col] = 0; res++; } // Traverse all neighbors que.push({row + 1, col}); que.push({row - 1, col}); que.push({row, col + 1}); que.push({row, col - 1}); } return res; } void printSizeOfConnected(vector<vector<int>> matrix) { // To store sizes vector<int> ans; int rows = matrix.size(); int cols = matrix[0].size(); for (int p = 0; p < rows; ++p) { for (int q = 0; q < cols; ++q) { // If the current cell is not visited if (matrix[p][q] == 1) { // To get the total number of connected nodes to the current node int sz = BFSTraversal(matrix, p, q, rows, cols); ans.push_back(sz); } } } cout << "The sizes of the connected nodes are "; for (int val : ans) cout << val << " "; } int main() { vector<vector<int>> matrix = {{0, 1, 0, 0, 0}, {0, 1, 1, 1, 1}, {1, 0, 0, 1, 1}, {1, 0, 0, 0, 0}, {0, 0, 1, 1, 1}}; printSizeOfConnected(matrix); return 0; }
Output
The sizes of the connected nodes are 7 2 3
Time complexity ? O(row*col) to traverse all cells of the matrix.
Space complexity ? O(row*col) to store pairs in the queue.
Approach 2
We will use the DFS traversal in this approach to find the size of the non?empty connected cells.
Algorithm
Step 1 ? Define the ?vis' list to track whether the particular cell of the matrix is visited.
Step 2 ? Start traversing the matrix using two nested loops.
Step 3 ? If the cell value is 1 and not visited, call the performDFS() function to find the size of the connected non?empty set.
Step 3.1 ? In the performDFS() function, update the vis[p][q] with 1, and increment the ?sz' by 1.
Step 3.2 ? Define the dirX[] and dirY[] array containing vertical and horizontal directions.
Step 3.3 ? Start traversing the dirX[] and dirY[] array to move in each direction.
Step 3.4 ? Check for the updated row and column value boundary validation. Also, the cell value is 1, and is not visited, so execute the performDFS() function for updated coordinates.
Step 4 ? Print the ?sz' value.
Example
#include <bits/stdc++.h> using namespace std; void performDFS(vector<vector<int>> &matrix, vector<vector<int>> &vis, int p, int q, int *sz) { // Current node is visited vis[p][q] = 1; (*sz)++; int dirX[] = {-1, 0, 1, 0}; int dirY[] = {0, 1, 0, -1}; // Traverse in all adjacent directions for (int k = 0; k < 4; k++) { int temp1 = p + dirX[k]; int temp2 = q + dirY[k]; // Validating the boundary conditions and checking if the current cell is non-visited if (temp1 >= 0 && temp1 < matrix.size() && temp2 >= 0 && temp2 < matrix[0].size() && matrix[temp1][temp2] && !vis[temp1][temp2]) { // Making recursive calls for all nodes performDFS(matrix, vis, temp1, temp2, sz); } } } int main() { vector<vector<int>> matrix = { {1, 0, 1, 0}, {1, 0, 0, 1}, {0, 1, 0, 0}, {1, 1, 0, 1}}; int rows = matrix.size(); int cols = matrix[0].size(); vector<vector<int>> vis(rows, vector<int>(cols, 0)); cout << "The sizes of the connected nodes are "; // Traverse the matrix and count the size of each connected component for (int p = 0; p < rows; p++) { for (int q = 0; q < cols; q++) { if (matrix[p][q] && !vis[p][q]) { int sz = 0; performDFS(matrix, vis, p, q, &sz); cout << sz << " "; } } } return 0; }
Output
The sizes of the connected nodes are 2 1 1 3 1
Time complexity ? O(row*col)
Space complexity ? O(1)
The BFS and DFS traversal gives the same result. However, DFS traversal doesn't take the dynamic memory. Whenever programmers need to find the shortest path or something like that, it is recommended to use the BFS traversal. Otherwise, programmers can use any of BFS or DFS traversal.