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

📅  最后修改于: 2021-09-07 05:27:54             🧑  作者: Mango

给定两个长度分别为NM 的二进制数组A[]B[] ,任务是在通过将两个数组相乘生成的矩阵C[][] 中找到区域K 中1组成的矩形的数量这样, 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


Javascript
# 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


输出:
// C# Program to implement
// the above approach
using System;
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];
            }
        }
        Console.Write(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

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live