📌  相关文章
📜  给定二进制数组中面积为K的矩形的计数仅由1组成

📅  最后修改于: 2021-04-30 03:00:37             🧑  作者: Mango

给定两个分别为NM的二进制数组A []B [] ,任务是在通过将两个数组相乘生成的矩阵C [] []中找到由1组成的区域K的矩形数。这样, C [i] [j] = A [i] * B [j] (1 < i < n,1 < j < m)。

例子:

天真的方法:解决问题的最简单方法是通过将两个数组相乘生成所需的矩阵,对于区域K的每个可能的矩形检查其是否仅由1组成。

时间复杂度: O(N * M * K)
辅助空间: O(N * M)

高效方法:为了优化上述方法,需要进行以下观察而不是生成矩阵:

因此,问题减少到从数组A []B []中找到仅包含所有可能长度的1的子数组,这些子数组是K的适当除数。请按照以下步骤解决问题:

  • 预先计算可能的子数组的数量。
  • 遍历K的所有除数,并针对每个可能的对( p,q )(其中p * q = K) ,检查A []和B []中是否存在长度为p,q的子数组。
  • 相应地增加可能的此类子数组的数量,最后打印获得的数量。

下面是上述方法的实现:

C++
0 1 1        0 1 1      0 1 1       0 1 1
0 1 1        0 1 1      0 1 1       0 1 1
0 0 0        0 0 0      0 0 0       0 0 0


Java
0 0 0        0 0 0
0 0 0        0 0 0
1 0 1        1 0 1
1 0 1        1 0 1


Python3
// C++ Program to implement
// the above approach
#include 
using namespace std;
  
// Function to find the subarrays of
// all possible lengths made up of only 1s
vector findSubarrays(vector& a)
{
    int n = a.size();
  
    // Stores the frequency
    // of the subarrays
    vector freq(n + 1);
  
    int count = 0;
  
    for (int i = 0; i < n; i++) {
        if (a[i] == 0) {
  
            // Check if the previous
            // value was also 0
            if (count == 0)
                continue;
  
            // If the previous value was 1
            else {
  
                int value = count;
                for (int j = 1; j <= count; j++) {
  
                    // Find the subarrays of
                    // each size from 1 to count
                    freq[j] += value;
                    value--;
                }
  
                count = 0;
            }
        }
  
        else
            count++;
    }
  
    // If A[] is of the form ....111
    if (count > 0) {
        int value = count;
        for (int j = 1; j <= count; j++) {
            freq[j] += value;
            value--;
        }
    }
  
    return freq;
}
  
// Function to find the count
// of all possible rectangles
void countRectangles(vector& a,
                     vector& b, int K)
{
    // Size of each of the arrays
    int n = a.size();
  
    int m = b.size();
  
    // Stores the count of subarrays
    // of each size consisting of
    // only 1s from array A[]
  
    vector subA
        = findSubarrays(a);
  
    // Stores the count of subarrays
    // of each size consisting of
    // only 1s from array B[]
    vector subB
        = findSubarrays(b);
  
    int total = 0;
  
    // Iterating over all subarrays
    // consisting of only 1s in A[]
    for (int i = 1; i < subA.size(); i++) {
  
        // If i is a factor of K, then
        // there is a subarray of size K/i in B[]
        if (K % i == 0 and (K / i) <= m) {
            total = total + subA[i] * subB[K / i];
        }
    }
  
    cout << total;
}
  
// Driver Code
int main()
{
    vector a = { 0, 0, 1, 1 };
  
    vector b = { 1, 0, 1 };
    int K = 2;
  
    countRectangles(a, b, K);
  
    return 0;
}


C#
// Java Program to implement
// the above approach
class GFG{
  
    // Function to find the subarrays of
    // all possible lengths made up of only 1s
    static int[] findSubarrays(int[] a)
    {
        int n = a.length;
  
        // Stores the frequency
        // of the subarrays
        int[] freq = new int[n + 1];
        int count = 0;
          for (int i = 0; i < n; i++) 
        {
            if (a[i] == 0) 
            {
  
                // Check if the previous
                // value was also 0
                if (count == 0)
                    continue;
  
                // If the previous value was 1
                else 
                {
                    int value = count;
                    for (int j = 1; j <= count; j++) 
                    {
  
                        // Find the subarrays of
                        // each size from 1 to count
                        freq[j] += value;
                        value--;
                    }
                    count = 0;
                }
            }
            else
                count++;
        }
  
        // If A[] is of the form ....111
        if (count > 0) 
        {
            int value = count;
            for (int j = 1; j <= count; j++) 
            {
                freq[j] += value;
                value--;
            }
        }
        return freq;
    }
  
    // Function to find the count
    // of all possible rectangles
    static void countRectangles(int[] a, int[] b, int K)
    {
        // Size of each of the arrays
        int n = a.length;
        int m = b.length;
  
        // Stores the count of subarrays
        // of each size consisting of
        // only 1s from array A[]
        int[] subA = findSubarrays(a);
  
        // Stores the count of subarrays
        // of each size consisting of
        // only 1s from array B[]
        int[] subB = findSubarrays(b);
  
        int total = 0;
  
        // Iterating over all subarrays
        // consisting of only 1s in A[]
        for (int i = 1; i < subA.length; i++) 
        {
  
            // If i is a factor of K, then
            // there is a subarray of size K/i in B[]
            if (K % i == 0 && (K / i) <= m) 
            {
                total = total + subA[i] * subB[K / i];
            }
        }
        System.out.print(total);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int[] a = {0, 0, 1, 1};
        int[] b = {1, 0, 1};
        int K = 2;
        countRectangles(a, b, K);
    }
}
  
// This code is contributed by shikhasingrajput


输出:
# Python3 program to implement
# the above approach
  
# Function to find the subarrays of
# all possible lengths made up of only 1s
def findSubarrays(a):
  
    n = len(a)
  
    # Stores the frequency
    # of the subarrays
    freq = [0] * (n + 1)
  
    count = 0
  
    for i in range(n): 
        if (a[i] == 0): 
  
            # Check if the previous
            # value was also 0
            if (count == 0):
                continue
  
            # If the previous value was 1
            else:
                value = count
                for j in range(1, count + 1): 
  
                    # Find the subarrays of
                    # each size from 1 to count
                    freq[j] += value
                    value -= 1
                  
                count = 0
                  
        else:
            count += 1
      
    # If A[] is of the form ....111
    if (count > 0):
        value = count
        for j in range(1, count + 1): 
            freq[j] += value
            value -= 1
          
    return freq
  
# Function to find the count
# of all possible rectangles
def countRectangles(a, b, K):
  
    # Size of each of the arrays
    n = len(a)
    m = len(b)
  
    # Stores the count of subarrays
    # of each size consisting of
    # only 1s from array A[]
    subA = []
    subA = findSubarrays(a)
  
    # Stores the count of subarrays
    # of each size consisting of
    # only 1s from array B[]
    subB = []
    subB = findSubarrays(b)
  
    total = 0
  
    # Iterating over all subarrays
    # consisting of only 1s in A[]
    for i in range(1, len(subA)): 
          
        # If i is a factor of K, then
        # there is a subarray of size K/i in B[]
        if (K % i == 0 and (K // i) <= m):
            total = total + subA[i] * subB[K // i]
          
    print(total)
  
# Driver Code
a = [ 0, 0, 1, 1 ]
b = [ 1, 0, 1 ]
  
K = 2
  
countRectangles(a, b, K)
  
# This code is contributed by code_hunt

时间复杂度: O(D)* O(N + M),其中D是K的除数。
辅助空间: O(N + M)