找出可以从给定矩阵形成的角矩形的数量
给定一个维度为N*M的二进制矩阵mat[][] ,任务是找出可以形成的角矩形的数量。角矩形定义为在其角上具有1的子矩阵,并且每个1必须属于该子矩阵中的唯一单元格。
例子:
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
方法:给定的问题可以通过使用由N C 2给出的 N 个点的所有不同可能对的概念来解决。这个想法是将具有值为1s的单元对(i, j)的频率存储在对的映射中,例如M 。生成频率图后,找到使用上述公式形成的角矩形的总数。请按照以下步骤解决给定的问题:
- 初始化一个变量,比如存储角矩形的结果计数的计数。
- 初始化一个映射,例如m[] ,它存储具有值为1的单元格(i, j)的频率。
- 使用变量i遍历范围[0, M)并执行以下任务:
- 使用变量j迭代范围[0, N)并且如果mat[i][j]等于1则使用变量k迭代范围[j_+1, N)并且如果mat[i][的值k]等于1 ,然后将m[{j, k}]的计数增加1。
- 使用变量it遍历映射m[]并将it.second*(it.second – 1)/2的值添加到变量count 中。
- 执行上述步骤后,打印count的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find all possible rectangles
// having distinct corners as 1s
int countCornerRectangles(
vector >& mat)
{
// Stores the count of rectangles
int count = 0;
int N = mat.size();
int M = mat[0].size();
// Map to store the frequency
map, 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 th
// 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 > 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 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 th
// 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 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 th
# 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.
Javascript
输出:
9
时间复杂度: O(N*M 2 )
辅助空间: O(M 2 )