📌  相关文章
📜  1到N的两个不同排列中的公共子数组的计数

📅  最后修改于: 2021-06-25 14:17:26             🧑  作者: Mango

给定两个具有相同长度N的数组AB ,并填充了从1N的自然数的排列,任务是计算AB中公共子数组的数量。
例子:

天真的方法:
想法是分别生成AB的所有子阵列,每个子阵列将采用O(N 2 ) 。现在,将A的所有子阵列与B的所有子阵列进行比较,并计算公共子阵列。这需要O(N 4 )
高效方法:
这个想法是使用哈希来有效地解决这个问题。

  1. 创建一个大小为N + 1的哈希数组H。
  2. 用它们各自的索引表示A的所有元素:
Element      Representaion
A[0]      0
A[1]      1
A[2]      2
.
.
and so on.
  1. 使用数组H来存储此表示, H [A [i]] = i
  2. 使用H根据此新表示更新B的元素, B [i] = H [B [i]]
  3. 现在,数组A可以表示为[0,1,2,..N],因此只需对B中具有连续元素的子数组的数量进行计数即可。一旦我们获得了连续元素的子数组的长度K ,就可以使用以下关系式计算总的可能子数组:

查看此示例以详细了解此方法:

下面是上述方法的实现:

C++
// C++ implementation of above approach
#include
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


Java
// 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


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


C#
// 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


Javascript


输出:
4
7

时间复杂度: O(N)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。