Find the Number of 'X' Total Shapes


In this problem, we need to find the total number of ‘X’ shapes in the given matrix. We can construct the single ‘X’ shape using 1 or more adjacent ‘X’ elements.

We can use the DFS (depth−first search) technique to solve the problem. For each ‘X’ element, we can find all adjacent elements using DFS and count it as a single ‘X’ shape. If we find a new ‘X’, we find its adjacent again.

Here, we will use the iterative and recursive DFS to find the total number of ‘X” shapes.

Problem statement − We have given a matrix[] of size N*M containing the ‘X’ and ‘O’ characters. We need to find the total number of ‘X’ shapes in the given matrix. The one ‘X’ shape contains 1 or more vertically and horizontally adjacent ‘X’ elements.

Sample examples

Input

matrix = {{'O', 'O', 'X'}, {'O', 'X', 'X'}, {'X', 'X', 'X'}}

Output

1

Explanation − Here, all X are adjacent. So, we can create only a single shape.

O O X
O X X
O X X

Input

matrix = {{'X', 'O', 'X'}, {'O', 'O', 'X'}, {'X', 'X', 'X'}}

Output

2

Explanation

The first shape is :-
X O O
O - -
- - -
The second shape is :-
- O X 
O O X
X X X

Approach 1

In this approach, we will use the recursive DFS technique to find the total number of ‘X’ shapes in the given matrix.

Algorithm

Step 1 − Initialize the ‘cnt’ with 0 to store the count of total number of ‘X’ shapes.

Step 2 − Start traversing the matrix using two nested loops.

Step 3 − If the current element is ‘X’, increment the ‘cnt’ by 1, and execute the performDFS() function to replace all adjacent ‘X’ with ‘O’.

Step 4 − Define the performDFS() function.

Step 4.1 − If index p is less than 0, q is less than 0, p is greater than the total rows of the matrix, or q is greater than the total rows of the matrix, execute the return statement.

Step 4.2 − If matrix[p][q] is ‘X’, update it with ‘O’.

Step 4.3 − Make a recursive call for all 4 directions to visit adjacent ‘X’ elements.

Step 5 − Return the ‘cnt’ value.

Example

#include <bits/stdc++.h>
using namespace std;

void performDFS(vector<vector<char>> &matrix, int p, int q) {
    if (p < 0 || q < 0 || p >= matrix.size() || matrix[p].size() <= q) {
        return;
    }
    if (matrix[p][q] == 'X') {
        // Update element with 'O'
        matrix[p][q] = 'O';
        // Recursively call DFS in all 4 directions
        performDFS(matrix, p + 1, q);
        performDFS(matrix, p, q + 1);
        performDFS(matrix, p - 1, q);
        performDFS(matrix, p, q - 1);
    }
}
int findXShape(vector<vector<char>> &matrix) {
    int rows = matrix.size();
    int cols = matrix[0].size();
    int cnt = 0;
    for (int p = 0; p < matrix.size(); p++) {
        for (int q = 0; q < matrix[p].size(); q++) {
            // performing DFS on each element having a value 'X'
            if (matrix[p][q] == 'X') {
                cnt++;
                performDFS(matrix, p, q);
            }
        }
    }
    return cnt;
}
int main() {
    vector<vector<char>> matrix = {{'O', 'O', 'X'},
                                   {'O', 'X', 'X'},
                                   {'X', 'X', 'X'}};
    cout << "The total number of X shape in the given matrix is " << findXShape(matrix) << endl;
    return 0;
}

Output

The total number of X shape in the given matrix is 1

Time complexity − − O(N*M*N*M), where (N*M) is for matrix traversal, and O(N*M) is to perform the DFS.

Space complexity − O(1), as we don’t use any extra space.

Approach 2

In this approach, we will use the ‘while’ loop to perform the depth-first search. Also, we will use the stack data structure to track the last visited array elements.

Algorithm

Step 1 − Initialize the ‘cnt’ with 0, and traverse the given matrix using two nested loops.

Step 2 − If the current element is ‘X’, increment the ‘cnt’ value by 1, and execute the performDFS() function.

Step 3.1 − In the performDFS() function, define the ‘pairSt’ stack and push the {0, 0} to the stack.

Step 3.2 − Traverse the stack until it becomes empty.

Step 3.3 − Pop up the top element from the stack, and store its first and second elements into the ‘x’ and ‘y’ variables, respectively.

Step 3.4 − If the current element is ‘X”, update it with the ‘O’.

Step 3.5 − If any adjacent ‘X’ element exists, push the index to the stack.

Step 4 − Return ‘cnt’ value.

Example

#include <bits/stdc++.h>
using namespace std;
int subArrSum(int nums[], int len, int k){
   int totalSum = 0;
   // Deques to store indices of the current window in increasing and decreasing order, respectively;
   deque<int> inc(k), dec(k);
   // Handling the first window
   int p = 0;
   for (p = 0; p < k; p++){
      // Remove elements which are greater than the current element
      while ((!inc.empty()) && nums[inc.back()] >= nums[p])
      inc.pop_back();
      // Remove elements from dec deque which are smaller than the current element
      while ((!dec.empty()) && nums[dec.back()] <= nums[p])
      dec.pop_back(); // Remove from rear
      // Add the nums[p] at last
      inc.push_back(p);
      dec.push_back(p);
   }
   // Hanlding other windows
   for (; p < len; p++){
      // get the first element from both the queues, and add them
      totalSum += nums[inc.front()] + nums[dec.front()];
      // Removing elements of the previous window
      while (!inc.empty() && inc.front() <= p - k)
      inc.pop_front();
      while (!dec.empty() && dec.front() <= p - k)
      dec.pop_front();
      while ((!inc.empty()) && nums[inc.back()] >= nums[p])
      inc.pop_back();
      while ((!dec.empty()) && nums[dec.back()] <= nums[p])
      dec.pop_back();
      inc.push_back(p);
      dec.push_back(p);
   }
   // Last window sum
   totalSum += nums[inc.front()] + nums[dec.front()];
   return totalSum;
}
int main() {
   int nums[] = {3, 5, -2, 6, 4, 8, -9, 10, -5};
   int len = sizeof(nums) / sizeof(nums[0]);
   int K = 4;
   cout << "The ans of minimum and maximum elements of all subarrays of size K is " << subArrSum(nums, len, K);
   return 0;
}

Output

The ans of minimum and maximum elements of all subarrays of size K is 15

Time complexity − O(N*M*N*M), where (N*M) is for traversing the matrix, and O(N*M) to perform the DFS.

Space complexity − O(N*M) to store the index pairs in the matrix.

We learned to implement the iterative and recursive DFS in the matrix. Sometimes, it is also useful to implement the DFS in the matrix to solve matrix-related complex problems.

Updated on: 22-Jul-2023

84 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements