Length of longest common prime subsequence from two given arrays

Given two arrays arr1[] and arr2[] of length N and M respectively, the task is to find the length of the longest common prime subsequence that can be obtained from the two given arrays.

Examples: 

Input: arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, arr2[] = {2, 5, 6, 3, 7, 9, 8} 
Output:
Explanation: 
The longest common prime subsequence present in both the arrays is {2, 3, 5, 7}.

Input: arr1[] = {1, 3, 5, 7, 9}, arr2[] = {2, 4, 6, 8, 10} 
Output:
Explanation: 
In the above arrays, the prime subsequence of arr1[] is {1, 3, 5, 7} and arr2[] is {2}. Therefore, there is no common prime numbers which are present in both the arrays. Hence, the result is 0.

Naive Approach: The simplest idea is to consider all subsequences of arr1[] and check if all numbers in this subsequence are prime and appear in arr2[]. Then find the longest length of these subsequences.



Time Complexity: O(M * 2N
Auxiliary Space: O(N)

Efficient Approach: The idea is to find all the prime numbers from both the arrays and then find the longest common prime subsequence from them using Dynamic Programming. Follow the steps below to solve the problem: 

  1. Find all the prime numbers between the minimum element of the array and maximum element of the array using Sieve Of Eratosthenes algorithm.
  2. Store the sequence of primes from the arrays arr1[] and arr2[].
  3. Find the LCS of the two sequences of primes.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the LCS
int recursion(vector<int> arr1,
              vector<int> arr2, int i,
              int j, map<pair<int, int>,
              int> dp)
{
    if (i >= arr1.size() or j >= arr2.size())
        return 0;
    pair<int, int> key = { i, j };
    if (arr1[i] == arr2[j])
        return 1
               + recursion(arr1, arr2,
                            i + 1, j + 1,
                           dp);
    if (dp.find(key) != dp.end())
        return dp[key];
 
    else
        dp[key] = max(recursion(arr1, arr2,
                                i + 1, j, dp),
                      recursion(arr1, arr2, i,
                                j + 1, dp));
    return dp[key];
}
 
// Function to generate
// all the possible
// prime numbers
vector<int> primegenerator(int n)
{
    int cnt = 0;
    vector<int> primes(n + 1, true);
    int p = 2;
    while (p * p <= n)
    {
        for (int i = p * p; i <= n; i += p)
            primes[i] = false;
        p += 1;
    }
    return primes;
}
 
// Function which returns the
// length of longest common
// prime subsequence
int longestCommonSubseq(vector<int> arr1,
                        vector<int> arr2)
{
 
    // Minimum element of
    // both arrays
    int min1 = *min_element(arr1.begin(),
                            arr1.end());
    int min2 = *min_element(arr2.begin(),
                            arr2.end());
 
    // Maximum element of
    // both arrays
    int max1 = *max_element(arr1.begin(),
                            arr1.end());
    int max2 = *max_element(arr2.begin(),
                            arr2.end());
 
    // Generating all primes within
    // the max range of arr1
    vector<int> a = primegenerator(max1);
 
    // Generating all primes within
    // the max range of arr2
    vector<int> b = primegenerator(max2);
 
    vector<int> finala;
    vector<int> finalb;
 
    // Store precomputed values
    map<pair<int, int>, int> dp;
 
    // Store all primes in arr1[]
    for (int i = min1; i <= max1; i++)
    {
        if (find(arr1.begin(), arr1.end(), i)
            != arr1.end()
            and a[i] == true)
            finala.push_back(i);
    }
 
    // Store all primes of arr2[]
    for (int i = min2; i <= max2; i++)
    {
        if (find(arr2.begin(), arr2.end(), i)
            != arr2.end()
            and b[i] == true)
            finalb.push_back(i);
    }
 
    // Calculating the LCS
    return recursion(finala, finalb, 0, 0, dp);
}
 
// Driver Code
int main()
{
    vector<int> arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    vector<int> arr2 = { 2, 5, 6, 3, 7, 9, 8 };
     
    // Function Call
    cout << longestCommonSubseq(arr1, arr2);
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python implementation of the above approach
 
# Function to calculate the LCS
 
def recursion(arr1, arr2, i, j, dp):
    if i >= len(arr1) or j >= len(arr2):
        return 0
    key = (i, j)
    if arr1[i] == arr2[j]:
        return 1 + recursion(arr1, arr2,
                             i + 1, j + 1, dp)
    if key in dp:
        return dp[key]
    else:
        dp[key] = max(recursion(arr1, arr2,
                                i + 1, j, dp),
                      recursion(arr1, arr2,
                                i, j + 1, dp))
    return dp[key]
 
# Function to generate
# all the possible
# prime numbers
 
 
def primegenerator(n):
    cnt = 0
    primes = [True for _ in range(n + 1)]
    p = 2
    while p * p <= n:
        for i in range(p * p, n + 1, p):
            primes[i] = False
        p += 1
    return primes
 
# Function which returns the
# length of longest common
# prime subsequence
 
 
def longestCommonSubseq(arr1, arr2):
 
    # Minimum element of
    # both arrays
    min1 = min(arr1)
    min2 = min(arr2)
 
    # Maximum element of
    # both arrays
    max1 = max(arr1)
    max2 = max(arr2)
 
    # Generating all primes within
    # the max range of arr1
    a = primegenerator(max1)
 
    # Generating all primes within
    # the max range of arr2
    b = primegenerator(max2)
 
    finala = []
    finalb = []
 
    # Store precomputed values
    dp = dict()
 
    # Store all primes in arr1[]
    for i in range(min1, max1 + 1):
        if i in arr1 and a[i] == True:
            finala.append(i)
 
    # Store all primes of arr2[]
    for i in range(min2, max2 + 1):
        if i in arr2 and b[i] == True:
            finalb.append(i)
 
    # Calculating the LCS
    return recursion(finala, finalb,
                     0, 0, dp)
 
 
# Driver Code
arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr2 = [2, 5, 6, 3, 7, 9, 8]
 
# Function Call
print(longestCommonSubseq(arr1, arr2))

chevron_right


Output

4

Time Complexity: O(N * M) 
Auxiliary Space: O(N * M)

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.



Improved By : ipg2016107