Number of ways to select equal sized subarrays from two arrays having atleast K equal pairs of elements

Given two arrays A[] and B[], and an integer K, the task is to find the number of ways to select two subarrays of the same size, one from A and the other one from B such that the subarrays have at least K equal pairs of elements. (i.e. the number of pairs (A[i], B[j]) in the two selected subarrays such that A[i] = B[j] >= K).
Examples: 

Input: A[] = {1, 2}, B[] = {1, 2, 3}, K = 1 
Output:
The ways to select two subarrays are:  

  1. [1], [1]
  2. [2], [2]
  3. [1, 2], [1, 2]
  4. [1, 2], [2, 3]

Input: A[] = {3, 2, 5, 21, 15, 2, 6}, B[] = {2, 1, 4, 3, 6, 7, 9}, K = 2 
Output:

Approach:  

mat[i][j] = 0, if A[i] != B[j]
          = 1, if A[i] = B[j]

Below is the implementation of the above approach:  

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to count the
// number of ways to select equal
// sized subarrays such that they
// have atleast K common elements
 
#include <bits/stdc++.h>
 
using namespace std;
 
// 2D prefix sum for submatrix
// sum query for matrix
int prefix_2D[2005][2005];
 
// Function to find the prefix sum
// of the matrix from i and j
int subMatrixSum(int i, int j, int len)
{
    return prefix_2D[i][j] -
           prefix_2D[i][j - len] -
           prefix_2D[i - len][j] +
           prefix_2D[i - len][j - len];
}
 
// Function to count the number of ways
// to select equal sized subarrays such
// that they have atleast K common elements
int numberOfWays(int a[], int b[], int n,
                            int m, int k)
{
 
    // Combining the two arrays
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i - 1] == b[j - 1])
                prefix_2D[i][j] = 1;
 
            else
                prefix_2D[i][j] = 0;
        }
    }
 
    // Calculating the 2D prefix sum
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            prefix_2D[i][j] += prefix_2D[i][j - 1];
        }
    }
 
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            prefix_2D[i][j] += prefix_2D[i - 1][j];
        }
    }
 
    int answer = 0;
 
    // iterating through all
    // the elements of matrix
    // and considering them to
    // be the bottom right
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
             
            // applying binary search
            // over side length
            int low = 1;
            int high = min(i, j);
 
            while (low < high) {
                int mid = (low + high) >> 1;
 
                // if sum of this submatrix >=k then
                // new search space will be [low, mid]
                if (subMatrixSum(i, j, mid) >= k) {
                    high = mid;
                }
                // else new search space
                // will be [mid+1, high]
                else {
                    low = mid + 1;
                }
            }
 
            // Adding the total submatrices
            if (subMatrixSum(i, j, low) >= k) {
                answer += (min(i, j) - low + 1);
            }
        }
    }
    return answer;
}
 
// Driver Code
int main()
{
    int N = 2, M = 3;
    int A[N] = { 1, 2 };
    int B[M] = { 1, 2, 3 };
 
    int K = 1;
 
    cout << numberOfWays(A, B, N, M, K);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to count the
// number of ways to select equal
// sized subarrays such that they
// have atleast K common elements
class GFG{
 
// 2D prefix sum for submatrix
// sum query for matrix
static int [][]prefix_2D = new int[2005][2005];
 
// Function to find the prefix sum
// of the matrix from i and j
static int subMatrixSum(int i, int j, int len)
{
    return prefix_2D[i][j] -
           prefix_2D[i][j - len] -
           prefix_2D[i - len][j] +
           prefix_2D[i - len][j - len];
}
 
// Function to count the number of ways
// to select equal sized subarrays such
// that they have atleast K common elements
static int numberOfWays(int a[], int b[], int n,
                        int m, int k)
{
     
    // Combining the two arrays
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          if (a[i - 1] == b[j - 1])
              prefix_2D[i][j] = 1;
          else
              prefix_2D[i][j] = 0;
       }
    }
 
    // Calculating the 2D prefix sum
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          prefix_2D[i][j] += prefix_2D[i][j - 1];
       }
    }
 
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          prefix_2D[i][j] += prefix_2D[i - 1][j];
       }
    }
 
    int answer = 0;
 
    // Iterating through all
    // the elements of matrix
    // and considering them to
    // be the bottom right
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
           
          // Applying binary search
          // over side length
          int low = 1;
          int high = Math.min(i, j);
           
          while (low < high)
          {
              int mid = (low + high) >> 1;
               
              // If sum of this submatrix >=k then
              // new search space will be [low, mid]
              if (subMatrixSum(i, j, mid) >= k)
              {
                  high = mid;
              }
               
              // Else new search space
              // will be [mid+1, high]
              else
              {
                  low = mid + 1;
              }
          }
           
          // Adding the total submatrices
          if (subMatrixSum(i, j, low) >= k)
          {
              answer += (Math.min(i, j) - low + 1);
          }
       }
    }
    return answer;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 2, M = 3;
    int A[] = { 1, 2 };
    int B[] = { 1, 2, 3 };
 
    int K = 1;
 
    System.out.print(numberOfWays(A, B, N, M, K));
}
}
 
// This code is contributed by Princi Singh
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to count the
# number of ways to select equal
# sized subarrays such that they
# have atleast K common element
 
# 2D prefix sum for submatrix
# sum query for matrix
prefix_2D = [[0 for x in range (2005)]
                for y in range (2005)]
 
# Function to find the prefix sum
# of the matrix from i and j
def subMatrixSum(i, j, length):
 
    return (prefix_2D[i][j] -
            prefix_2D[i][j - length] -
            prefix_2D[i - length][j] +
            prefix_2D[i - length][j - length])
 
# Function to count the number of ways
# to select equal sized subarrays such
# that they have atleast K common elements
def numberOfWays(a, b, n, m, k):
 
    # Combining the two arrays
    for i in range (1, n + 1):
        for j in range (1, m + 1):
            if (a[i - 1] == b[j - 1]):
                prefix_2D[i][j] = 1
            else:
                prefix_2D[i][j] = 0
       
    # Calculating the 2D prefix sum
    for i in range (1, n + 1):
        for j in range (1, m + 1):
            prefix_2D[i][j] += prefix_2D[i][j - 1]
        
    for i in range (1, n + 1):
        for j in range (1, m + 1):
            prefix_2D[i][j] += prefix_2D[i - 1][j]
    answer = 0
 
    # iterating through all
    # the elements of matrix
    # and considering them to
    # be the bottom right
    for i in range (1, n +1):
        for j in range (1, m + 1):
             
            # applying binary search
            # over side length
            low = 1
            high = min(i, j)
 
            while (low < high):
                mid = (low + high) >> 1
 
                # if sum of this submatrix >=k then
                # new search space will be [low, mid]
                if (subMatrixSum(i, j, mid) >= k):
                    high = mid
                 
                # else new search space
                # will be [mid+1, high]
                else:
                    low = mid + 1
 
            # Adding the total submatrices
            if (subMatrixSum(i, j, low) >= k):
                answer += (min(i, j) - low + 1)
          
    return answer
 
# Driver Code
if __name__ == "__main__":
               
    N = 2
    M = 3
    A = [1, 2]
    B = [1, 2, 3]
    K = 1
    print (numberOfWays(A, B, N, M, K))
 
# This code is contributed by Chitranayal
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to count the
// number of ways to select equal
// sized subarrays such that they
// have atleast K common elements
using System;
 
class GFG{
 
// 2D prefix sum for submatrix
// sum query for matrix
static int [,]prefix_2D = new int[2005, 2005];
 
// Function to find the prefix sum
// of the matrix from i and j
static int subMatrixSum(int i, int j, int len)
{
    return prefix_2D[i, j] -
           prefix_2D[i, j - len] -
           prefix_2D[i - len, j] +
           prefix_2D[i - len, j - len];
}
 
// Function to count the number of ways
// to select equal sized subarrays such
// that they have atleast K common elements
static int numberOfWays(int []a, int []b, int n,
                        int m, int k)
{
     
    // Combining the two arrays
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          if (a[i - 1] == b[j - 1])
              prefix_2D[i, j] = 1;
          else
              prefix_2D[i, j] = 0;
       }
    }
 
    // Calculating the 2D prefix sum
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          prefix_2D[i, j] += prefix_2D[i, j - 1];
            
       }
    }
 
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
          prefix_2D[i, j] += prefix_2D[i - 1, j];
       }
    }
 
    int answer = 0;
 
    // Iterating through all
    // the elements of matrix
    // and considering them to
    // be the bottom right
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= m; j++)
       {
            
          // Applying binary search
          // over side length
          int low = 1;
          int high = Math.Min(i, j);
          while (low < high)
          {
              int mid = (low + high) >> 1;
               
              // If sum of this submatrix >=k then
              // new search space will be [low, mid]
              if (subMatrixSum(i, j, mid) >= k)
              {
                  high = mid;
              }
               
              // Else new search space
              // will be [mid+1, high]
              else
              {
                  low = mid + 1;
              }
          }
           
          // Adding the total submatrices
          if (subMatrixSum(i, j, low) >= k)
          {
              answer += (Math.Min(i, j) - low + 1);
          }
       }
    }
    return answer;
}
 
// Driver Code
public static void Main(String[] args)
{
    int N = 2, M = 3;
    int []A = { 1, 2 };
    int []B = { 1, 2, 3 };
 
    int K = 1;
 
    Console.Write(numberOfWays(A, B, N, M, K));
}
}
 
// This code is contributed by Princi Singh
chevron_right

Output: 
4


 

Time Complexity: O(N * M * log(max(N, M)))




Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : princi singh, chitranayal

Article Tags :