Open In App

Find the number of corner rectangles that can be formed from given Matrix

Last Updated : 15 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary matrix mat[][] of dimensions N*M, the task is to find the number of corner rectangles that can be formed. A corner rectangle is defined as the submatrix having 1s on the corners of it and each 1s must belong to a unique cell in that submatrix.

Examples:

Input: mat[][] = {{1, 0, 1}, {0, 0, 0}, {1, 0, 1}}
Output: 1
Explanation:
There exists only one submatrix satisfying the given formula represented by bold as:
1 0 1
0 0 0
1 0 1

Input: mat[][] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}
Output: 9

Approach: The given problem can be solved by using the concepts of all distinct possible pairs from N points which are given by NC2. The idea is to store the frequency of pair of cells (i, j) having the values as 1s in the map of pairs, say M. After generating the frequency map find the total count of corners rectangle formed using the above formula. Follow the steps below to solve the given problem:

  • Initialize a variable, say count that stores the resultant count of corner rectangle.
  • Initialize a map, say m[] that stores the frequency of the cell (i, j) having values as 1.
  • Iterate over the range [0, M) using the variable i and perform the following tasks:
  • Traverse over the map m[] using the variable it and add the value of it.second*(it.second – 1)/2 to the variable count.
  • After performing the above steps, print the value of count as the answer.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find all possible rectangles
// having distinct corners as 1s
int countCornerRectangles(
    vector<vector<int> >& mat)
{
    // Stores the count of rectangles
    int count = 0;
 
    int N = mat.size();
    int M = mat[0].size();
 
    // Map to store the frequency
    map<pair<int, int>, int> m;
 
    // Iterate over each row
    for (int i = 0; i < N; i++) {
 
        // Iterate over each cell
        for (int j = 0; j < M; j++) {
            if (mat[i][j] == 1) {
 
                // Check for 1's of the
                // same column pair
                for (int k = j + 1;
                     k < M; k++) {
                    if (mat[i][k] == 1) {
                        m[{ j, k }]++;
                    }
                }
            }
        }
    }
 
    // For any pair of column cells (x, y)
    // If the frequency is n. Then choosing
    // any 2 will form a rectangle
    for (auto& it : m) {
        count
            += (it.second * (it.second - 1)) / 2;
    }
 
    return count;
}
 
// Driver Code
int main()
{
    vector<vector<int> > mat
        = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
 
    cout << countCornerRectangles(mat);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
import java.util.Map.Entry;
 
class GFG{
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Function to find all possible rectangles
// having distinct corners as 1s
static int countCornerRectangles(int[][] mat)
{
   
    // Stores the count of rectangles
    int count = 0;
 
    int N = mat.length;
    int M = mat[0].length;
 
    // Map to store the frequency
    HashMap<pair, Integer> m = new HashMap<>();
 
    // Iterate over each row
    for (int i = 0; i < N; i++) {
 
        // Iterate over each cell
        for (int j = 0; j < M; j++) {
            if (mat[i][j] == 1) {
 
                // Check for 1's of the
                // same column pair
                for (int k = j + 1;
                     k < M; k++) {
                    if (mat[i][k] == 1) {
                        if(m.containsKey(new pair(j,k)))
                        m.put( new pair(j,k), m.get(new pair(j,k))+1);
                        else
                            m.put( new pair(j,k), 1);
                    }
                }
            }
        }
    }
 
    // For any pair of column cells (x, y)
    // If the frequency is n. Then choosing
    // any 2 will form a rectangle
    for (Entry<pair, Integer> it : m.entrySet()){
        count
            += (it.getValue() * (it.getValue()+1)) / 2;
    }
 
    return count;
}
 
// Driver Code
public static void main(String[] args)
{
    int[][] mat
        = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
 
    System.out.print(countCornerRectangles(mat));
 
}
}
 
// This code is contributed by Rajput-Ji


Python3




# Python 3 program for the above approach
from collections import defaultdict
 
# Function to find all possible rectangles
# having distinct corners as 1s
def countCornerRectangles(mat):
 
    # Stores the count of rectangles
    count = 0
 
    N = len(mat)
    M = len(mat[0])
 
    # Map to store the frequency
    m = defaultdict(int)
 
    # Iterate over each row
    for i in range(N):
 
        # Iterate over each cell
        for j in range(M):
            if (mat[i][j] == 1):
 
                # Check for 1's of the
                # same column pair
                for k in range(j + 1, M):
                    if (mat[i][k] == 1):
                        m[(j, k)] += 1
 
    # For any pair of column cells (x, y)
    # If the frequency is n. Then choosing
    # any 2 will form a rectangle
    for it in m:
        count += (m[it] * (m[it] - 1)) // 2
 
    return count
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
 
    print(countCornerRectangles(mat))
 
    # This code is contributed by ukasp.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class pair {
  public int first, second;
  public pair(int first, int second)
  {
    this.first = first;
    this.second = second;
  }
}
 
class Program {
  static void Main(string[] args)
  {
    int[][] mat = new int[3][];
    mat[0] = new int[] { 1, 1, 1 };
    mat[1] = new int[] { 1, 1, 1 };
    mat[2] = new int[] { 1, 1, 1 };
 
    Console.WriteLine(countCornerRectangles(mat));
  }
 
  // Function to find all possible rectangles
  // having distinct corners as 1s
  static int countCornerRectangles(int[][] mat)
  {
    // Stores the count of rectangles
    int count = 0;
    int N = mat.Length;
    int M = mat[0].Length;
 
    // Map to store the frequency
    Dictionary<pair, int> m
      = new Dictionary<pair, int>();
 
    // Iterate over each row
    for (int i = 0; i < N; i++)
 
      // Iterate over each cell
      for (int j = 0; j < M; j++)
        if (mat[i][j] == 1)
 
          // Check for 1's of the
          // same column pair
          for (int k = j + 1; k < M; k++)
            if (mat[i][k] == 1)
              if (m.ContainsKey(
                new pair(j, k)))
                m.Add(new pair(j, k),
                      m[new pair(j, k)]
                      + 1);
    else
      m.Add(new pair(j, k), 1);
 
    // For any pair of column cells (x, y)
    // If the frequency is n. Then choosing
    // any 2 will form a rectangle
    foreach(var it in m) count
      += (it.Value * (it.Value + 1)) / 2;
 
    return count;
  }
}
// This code is contributed by Tapesh(tapeshdua420)


Javascript




<script>
       // JavaScript code for the above approach
 
       // Function to find all possible rectangles
       // having distinct corners as 1s
       function countCornerRectangles(
           mat)
           {
           // Stores the count of rectangles
           let count = 0;
 
           let N = mat.length;
           let M = mat[0].length;
 
           // Map to store the frequency
           let m = new Map();
 
           // Iterate over each row
           for (let i = 0; i < N; i++) {
 
               // Iterate over each cell
               for (let j = 0; j < M; j++) {
                   if (mat[i][j] == 1) {
 
                       // Check for 1's of the
                       // same column pair
                       for (let k = j + 1;
                           k < M; k++) {
                           if (mat[i][k] == 1) {
                               if (m.has({ first: j, second: k }))
                                   m.set({ first: j, second: k }, m.get({ first: j, second: k }) + 1);
                               else
                                   m.set({ first: j, second: k }, 1)
                           }
                       }
                   }
               }
           }
 
           // For any pair of column cells (x, y)
           // If the frequency is n. Then choosing
           // any 2 will form a rectangle
           for (let val of m.values()) {
               count += ((val * (val - 1)) / 2) + 1;
           }
 
           return count;
       }
 
       // Driver Code
       let mat
           = [[1, 1, 1], [1, 1, 1], [1, 1, 1]];
 
       document.write(countCornerRectangles(mat));
 
      // This code is contributed by Potta Lokesh
   </script>


Output: 

9

 

Time Complexity: O(N*M2)
Auxiliary Space: O(M2)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads