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++
#include <bits/stdc++.h>
using namespace std;
int countCornerRectangles(
vector<vector< int > >& mat)
{
int count = 0;
int N = mat.size();
int M = mat[0].size();
map<pair< int , int >, int > m;
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
if (mat[i][j] == 1) {
for ( int k = j + 1;
k < M; k++) {
if (mat[i][k] == 1) {
m[{ j, k }]++;
}
}
}
}
}
for ( auto & it : m) {
count
+= (it.second * (it.second - 1)) / 2;
}
return count;
}
int main()
{
vector<vector< int > > mat
= { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
cout << countCornerRectangles(mat);
return 0;
}
|
Java
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;
}
}
static int countCornerRectangles( int [][] mat)
{
int count = 0 ;
int N = mat.length;
int M = mat[ 0 ].length;
HashMap<pair, Integer> m = new HashMap<>();
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
if (mat[i][j] == 1 ) {
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 (Entry<pair, Integer> it : m.entrySet()){
count
+= (it.getValue() * (it.getValue()+ 1 )) / 2 ;
}
return count;
}
public static void main(String[] args)
{
int [][] mat
= { { 1 , 1 , 1 }, { 1 , 1 , 1 }, { 1 , 1 , 1 } };
System.out.print(countCornerRectangles(mat));
}
}
|
Python3
from collections import defaultdict
def countCornerRectangles(mat):
count = 0
N = len (mat)
M = len (mat[ 0 ])
m = defaultdict( int )
for i in range (N):
for j in range (M):
if (mat[i][j] = = 1 ):
for k in range (j + 1 , M):
if (mat[i][k] = = 1 ):
m[(j, k)] + = 1
for it in m:
count + = (m[it] * (m[it] - 1 )) / / 2
return count
if __name__ = = "__main__" :
mat = [[ 1 , 1 , 1 ], [ 1 , 1 , 1 ], [ 1 , 1 , 1 ]]
print (countCornerRectangles(mat))
|
C#
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));
}
static int countCornerRectangles( int [][] mat)
{
int count = 0;
int N = mat.Length;
int M = mat[0].Length;
Dictionary<pair, int > m
= new Dictionary<pair, int >();
for ( int i = 0; i < N; i++)
for ( int j = 0; j < M; j++)
if (mat[i][j] == 1)
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);
foreach ( var it in m) count
+= (it.Value * (it.Value + 1)) / 2;
return count;
}
}
|
Javascript
<script>
function countCornerRectangles(
mat)
{
let count = 0;
let N = mat.length;
let M = mat[0].length;
let m = new Map();
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (mat[i][j] == 1) {
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 (let val of m.values()) {
count += ((val * (val - 1)) / 2) + 1;
}
return count;
}
let mat
= [[1, 1, 1], [1, 1, 1], [1, 1, 1]];
document.write(countCornerRectangles(mat));
</script>
|
Time Complexity: O(N*M2)
Auxiliary Space: O(M2)