Count of common subarrays in two different permutations of 1 to N

Given two arrays A and B of the same length N, filled with a permutation of natural numbers from 1 to N, the task is to count the number of common subarrays in A and B.

Examples:

Input: A = [1, 2, 3], B = [2, 3, 1]
Output: 4
Explanation:
The common subarrays are [1], [2], [3], [2, 3]
Hence, total count = 4

Input: A = [1, 2, 3, 4, 5], B = [2, 3, 1, 4, 5]
Output: 7
Explanation:
The common subarrays are [1], [2], [3], [4], [5], [2, 3], [4, 5]
Hence, total count = 7

Naive Approach:
The idea is to generate all subarrays of A and B separately, which would take O(N2) for each array. Now, compare all subarrays of A with all subarrays of B and count common subarrays. It would take O(N4).



Efficient Approach:
The idea is to use Hashing to solve this problem efficiently.

  1. Create a Hash array H of size N+1.
  2. Represent all elements of A by their respective indices:
    Element      Representaion
    A[0]      0
    A[1]      1
    A[2]      2
    .
    .
    and so on.
    
  3. Use array H to store this representation, H[ A[ i ] ] = i
  4. Update the elements of B according to this new representation using H, B[ i ] = H[ B[ i ] ]
  5. Now, array A can be represented as [0, 1, 2, ..N], so simply count number of subarrays in B which have consecutive elements. Once we get length K of subarray of consecutive elements, count total possible subarray using following relation:

    Total number of subarrays = (K * (K + 1)) / 2

Look at this example to understand this approach in detail:

Example:
A = [4, 3, 1, 2, 5]
B = [3, 1, 2, 4, 5]
Common subarrays are [1], [2], [3], [4], [5], [3, 1], [1, 2], [3, 1, 2] = 8

1. Represent A[i] as i, and store in H as H[A[i]] = i, Now array H from index 1 to N is,
H = [2, 3, 1, 0, 4]

2. Update B according to H, B[i] = H[B[i]]
B = [1, 2, 3, 0, 4]

3. Look for subarray in B with consecutive elements,
Subarray from index 0 to 2 is [1, 2, 3], consisting of consecutive elements with length K = 3
Element at index 3 forms a subarray [0] of length K = 1
Element at index 4 forms a subarray [4] of length K = 1

4. Total number of common subarrays =
(3*(3+1))/2 + (1*(1+1))/2 + (1*(1+1))/2 = 6 + 1 + 1 = 8

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of above approach
#include<bits/stdc++.h> 
using namespace std; 
  
int commonSubarrays(int *A, int *B, int N)
{
    // Initialising Map for 
    // Index Mapping
    int Map[N + 1];
  
    // Mapping elements of A
    for(int i = 0 ; i< N; i++)
        Map[*(A + i)] = i;
  
    // Modify elements of B
    // according to Map
    for (int i = 0; i < N; i++) 
    
        // Changing B[i] as
        // the index of B[i] in A
        *(B + i) = Map[*(B + i)];
    }
      
    // Count of common subarrays
    int count = 0;
  
    // Traversing array B
    int i = 0, K;
    while (i < N)
    {
        K = 1;
        i+= 1;
  
        // While consecutive elements
        // are found, we increment K
        while (i < N && B[i] == B[i - 1] + 1)
        
            i += 1;
            K += 1;
        }
          
        // Add number of subarrays 
        //with length K 
        // to total count
        count = count + ((K) * (K + 1)) / 2;
    }
    return count; 
  
// Driver code 
int main() 
{
    int N = 3;
    int A[] = {1, 2, 3};
    int B[] = {2, 3, 1};
    cout << (commonSubarrays(A, B, N))
         << endl;
  
    N = 5;
    int C[] = {1, 2, 3, 4, 5};
    int D[] = {2, 3, 1, 4, 5};
    cout << (commonSubarrays(C, D, N));
}
  
// This code is contributed by chitranayal

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above approach
class GFG{ 
  
static int commonSubarrays(int []A, 
                           int []B, int N)
{
      
    // Initialising Map for 
    // Index Mapping
    int []Map = new int[N + 1];
  
    // Mapping elements of A
    for(int i = 0; i< N; i++)
       Map[A[i]] = i;
  
    // Modify elements of B
    // according to Map
    for(int i = 0; i < N; i++) 
    
         
       // Changing B[i] as
       // the index of B[i] in A
       B[i] = Map[B[i]];
    }
      
    // Count of common subarrays
    int count = 0;
  
    // Traversing array B
    int i = 0, K;
    while (i < N)
    {
        K = 1;
        i+= 1;
  
        // While consecutive elements
        // are found, we increment K
        while (i < N && B[i] == B[i - 1] + 1)
        
            i += 1;
            K += 1;
        }
          
        // Add number of subarrays 
        //with length K 
        // to total count
        count = count + ((K) * (K + 1)) / 2;
    }
    return count; 
  
// Driver code 
public static void main(String[] args) 
{
    int N = 3;
    int A[] = {1, 2, 3};
    int B[] = {2, 3, 1};
    System.out.print(commonSubarrays(A, B, N));
    System.out.print("\n");
      
    N = 5;
    int C[] = {1, 2, 3, 4, 5};
    int D[] = {2, 3, 1, 4, 5};
    System.out.print(commonSubarrays(C, D, N));
}
}
  
// This code is contributed by gauravrajput1

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of above approach
  
def commonSubarrays(A, B, N):
  
    # Initialising Map for 
    # Index Mapping
    Map = [0 for i in range(N + 1)]
  
    # Mapping elements of A
    for i in range(N):
        Map[A[i]]= i
  
    # Modify elements of B
    # according to Map
    for i in range(N)    :
          
        # Changing B[i] as
        # the index of B[i] in A
        B[i]= Map[B[i]] 
  
    # Count of common subarrays
    count = 0 
  
    # Traversing array B
    i = 0
    while i<N:
        K = 1
        i+= 1
  
        # While consecutive elements
        # are found, we increment K
        while i<N and B[i]== B[i-1]+1:
            i+= 1 
            K+= 1
  
        # Add number of subarrays 
        # with length K 
        # to total count
        count = count + (
                   (K)*(K + 1))//2
  
    return count        
  
# Driver code
N = 3
A =[1, 2, 3]
B =[2, 3, 1]
print(commonSubarrays(A, B, N))
  
N = 5
A =[1, 2, 3, 4, 5]
B =[2, 3, 1, 4, 5]
print(commonSubarrays(A, B, N))

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the above approach
using System;
class GFG{ 
  
static int commonSubarrays(int []A, 
                           int []B, 
                           int N)
{
      
    // Initialising Map for 
    // Index Mapping
    int []Map = new int[N + 1];
  
    // Mapping elements of A
    for(int i = 0; i < N; i++)
       Map[A[i]] = i;
  
    // Modify elements of B
    // according to Map
    for(int i = 0; i < N; i++) 
    
         
       // Changing B[i] as
       // the index of B[i] in A
       B[i] = Map[B[i]];
    }
      
    // Count of common subarrays
    int count = 0;
  
    // Traversing array B
    int a = 0, K;
    while (a < N)
    {
        K = 1;
        a += 1;
  
        // While consecutive elements
        // are found, we increment K
        while (a < N && B[a] == B[a - 1] + 1)
        
            a += 1;
            K += 1;
        }
          
        // Add number of subarrays 
        //with length K 
        // to total count
        count = count + ((K) * (K + 1)) / 2;
    }
    return count; 
  
// Driver code 
public static void Main() 
{
    int N = 3;
    int []A = {1, 2, 3};
    int []B = {2, 3, 1};
    Console.Write(commonSubarrays(A, B, N));
    Console.Write("\n");
      
    N = 5;
    int []C = {1, 2, 3, 4, 5};
    int []D = {2, 3, 1, 4, 5};
    Console.Write(commonSubarrays(C, D, N));
}
}
  
// This code is contributed by Code_Mech

chevron_right


Output:

4
7

Time complexity: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

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.