Queries to find the count of connected Non-Empty Cells in a Matrix with update


A matrix can be thought of as a collection of cells organized in rows and columns. Each cell can contain a value, which can be either empty or non-empty. In computer programming, matrices are commonly used to represent data in a two-dimensional grid.

In this article, we will discuss how to efficiently count the number of connected non-empty cells in a matrix, taking into account possible updates to the matrix. We will explore different approaches to solve this problem and provide real code examples to demonstrate the implementation.

Syntax

The basic syntax for querying the count of connected non-empty cells in a matrix with updates using C/C++ can be defined as follows −

int queryCount(int matrix[][MAX_COLS], int rows, int cols);

where matrix is the input ‘matrix’, ‘rows’ and ‘cols’ represent the number of rows and columns in the matrix, respectively. The function ‘queryCount’ returns an integer value representing the count of connected non-empty cells in the matrix.

Algorithm

To solve this problem, we can follow the following algorithm −

Step 1 − Initialize a variable ‘count’ to 0, which will store the count of connected non-empty cells.

Step 2 − Iterate through each cell in the matrix.

Step 3 − For each cell, check if it is non-empty (i.e., contains a value other than empty).

Step 4 − If the cell is non-empty, increment the ‘count’ by 1.

Step 5 − Check if the cell has any neighboring cells that are also non-empty.

Step 6 − If a neighboring cell is non-empty, increment the ‘count’ by 1.

Step 7 − Repeat steps 5-6 for all neighboring cells.

Step 8 − 8: After iterating through all cells in the matrix, return the ‘count’ as the final result.

Approaches

  • Approach 1 − One common approach to solve this problem is to use Depth-First Search (DFS) algorithm

  • Approach 2 − Another approach to implement the queries to find the count of connected non-empty cells in a matrix with updates is to use a Breadth-First Search (BFS) algorithm.

Approach 1

In this approach, the DFS algorithm involves traversing the matrix recursively and keeping track of visited cells to avoid repeated counting.

Example-1

This approach executes a Depth-First Search on a two-dimensional matrix. The dimensions of the matrix, the cell values, and the number of inquiries are all randomly determined. The countConnectedCells subroutine performs the DFS and returns the count of interconnected, non-null cells, beginning from the cell located at the designated row and column. The updateCell function updates the value of a cell in the matrix. The main function initiates the random seed using the current time, then generates a random matrix size and elements, followed by a random number of inquiries. For each inquiry, the code randomly selects either a count query (1) or an update query (2) and performs the corresponding action. If the query is of type 1, the countConnectedCells function is invoked to determine the count of interconnected non-null cells and the result is printed. If the query is of type 2, the updateCell function is called to adjust the value of the specified cell.

#include <iostream>
using namespace std;

const int MAX_SIZE = 100; // Maximum size of the matrix

// Function to count connected non-empty cells using DFS
int countConnectedCells(int matrix[][MAX_SIZE], int rows, int cols, int row, int col, int visited[][MAX_SIZE]) {
   if (row < 0 || row >= rows || col < 0 || col >= cols || matrix[row][col] == 0 || visited[row][col])
      return 0;

   visited[row][col] = 1;
   int count = 1; // Counting the current cell as non-empty
   count += countConnectedCells(matrix, rows, cols, row - 1, col, visited); // Check top cell
   count += countConnectedCells(matrix, rows, cols, row + 1, col, visited); // Check bottom cell
   count += countConnectedCells(matrix, rows, cols, row, col - 1, visited); // Check left cell
   count += countConnectedCells(matrix, rows, cols, row, col + 1, visited); // Check right cell

   return count;
}

// Function to update a cell in the matrix
void updateCell(int matrix[][MAX_SIZE], int rows, int cols, int row, int col, int newValue) {
   matrix[row][col] = newValue;
}

// Function to initialize the matrix
void initializeMatrix(int matrix[][MAX_SIZE], int rows, int cols) {
   for (int i = 0; i <rows; i++) {
      for (int j = 0; j < cols; j++) {
         cin >> matrix[i][j]; // Taking input for each cell in the matrix
      }
   }
}

int main() {
   int rows, cols; // Input matrix size
   cin >> rows >> cols; // Taking input for matrix size

   int matrix[MAX_SIZE][MAX_SIZE]; // Matrix to store the values
   int visited[MAX_SIZE][MAX_SIZE] = {0}; // Visited matrix to keep track of visited cells

   initializeMatrix(matrix, rows, cols); // Initialize the matrix with input values

   int queries; // Input number of queries
   cin >> queries; // Taking input for number of queries

   for (int i = 0; i < queries; i++) {
      int queryType; // Input query type (1 for count query, 2 for update query)
      cin >> queryType; // Taking input for query type

      if (queryType == 1) {
         int row, col; // Input row and column for count query
         cin >> row >> col; // Taking input for row and column
         int count = countConnectedCells(matrix, rows, cols, row, col, visited); // Call countConnectedCells function
         cout << "Count of connected non-empty cells at (" << row << ", " << col << "): " << count << endl; // Print result
      } else if (queryType == 2) {
         int row, col, newValue; // Input row, column, and new value for update query
         cin >> row >> col >> newValue; // Taking input for row, column, and new value
         updateCell(matrix, rows, cols, row, col, newValue); // Call updateCell function
      }
   }
   return 0;
}

Output

Count of connected non-empty cells at (1, 2): 0
Count of connected non-empty cells at (0, 1): 2

Approach 2

In this approach, Breadth-First Search (BFS) is another graph traversal algorithm that can be used to find the count of connected non-empty cells in a matrix. In BFS, we start from a given cell and explore all its adjacent cells in a breadth-first manner, i.e., level by level. We use a queue to keep track of the cells to be visited and mark the visited cells to avoid counting them multiple times.

Example 2

The code constitutes a software that executes a Breadth-First Search algorithm on a 2-dimensional matrix. The dimensions of the matrix, the cell values, and the quantity of inquiries are arbitrarily generated. The code comprises two subroutines: one for carrying out the BFS and another for adjusting a cell within the matrix.

The BFS operation initiates from a randomly chosen cell and inspects its neighboring cells to determine if they are interlinked and unoccupied. If so, they are appended to a queue and processed in a similar fashion. Updating a cell within the matrix involves merely altering its value. After the matrix and the number of inquiries have been generated, the code randomly selects either a BFS query or an update query and performs the appropriate action. The outcome of a BFS query is the tally of interlinked unoccupied cells, starting from the selected cell.

Code

#include <iostream>
#include <queue>
#include <ctime>
#include <cstdlib>

using namespace std;

const int MAX_SIZE = 100;

// Function to perform Breadth-First Search (BFS)
int bfs(int matrix[][MAX_SIZE], int rows, int cols, int row, int col, int visited[][MAX_SIZE]) {
   int count = 0;
   queue<pair<int, int>> q;
   q.push({row, col});

   while (!q.empty()) {
      pair<int, int> currentCell = q.front();
      q.pop();

      int currentRow = currentCell.first;
      int currentCol = currentCell.second;

      if (currentRow >= 0 && currentRow <rows && currentCol >= 0 && currentCol < cols && !visited[currentRow][currentCol] && matrix[currentRow][currentCol] == 1) {
         count++;
         visited[currentRow][currentCol] = 1;

         q.push({currentRow - 1, currentCol});
         q.push({currentRow + 1, currentCol});
         q.push({currentRow, currentCol - 1});
         q.push({currentRow, currentCol + 1});
      }
   }
   return count;
}
// Function to update a cell in the matrix
void updateCell(int matrix[][MAX_SIZE], int row, int col, int newValue) {
   matrix[row][col] = newValue;
}

// Function to generate a random integer between min and max (inclusive)
int randomInt(int min, int max) {
   return rand() % (max - min + 1) + min;
}

int main() {
   srand(time(0));

   int rows = randomInt(1, 10);
   int cols = randomInt(1, 10);

   int matrix[MAX_SIZE][MAX_SIZE];
   int visited[MAX_SIZE][MAX_SIZE] = {0};

   for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
         matrix[i][j] = randomInt(0, 1);
      }
   }

   int queries = randomInt(1, 5);

   for (int i = 0; i < queries; i++) {
      int queryType = randomInt(1, 2);

      if (queryType == 1) {
         int row = randomInt(0, rows - 1);
         int col = randomInt(0, cols - 1);
         int count = bfs(matrix, rows, cols, row, col, visited);
         cout << "Count of connected non-empty cells at (" << row << ", " << col << "): " << count << endl;
      } else if (queryType == 2) {
         int row = randomInt(0, rows - 1);
         int col = randomInt(0, cols - 1);
         int newValue = randomInt(0, 1);
         updateCell(matrix, row, col, newValue);
      }
   }
   return 0;
}

Output

Count of connected non-empty cells at (0, 0): 0

Conclusion

In this article, we discussed two approaches to find the count of connected non-empty cells in a matrix with updates using C/C++. Depth-first search (DFS) algorithm and the Union-Find (Disjoint Set Union). It's important to analyze the time complexity and space complexity of each approach before choosing the most suitable one for a particular use case.

Updated on: 21-Jul-2023

35 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements