Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

Longest subsequence such that every element in the subsequence is formed by multiplying previous element with a prime

  • Difficulty Level : Medium
  • Last Updated : 21 May, 2021

Given a sorted array of N integers. The task is to find the longest subsequence such that every element in the subsequence is reachable by multiplying any prime number to the previous element in the subsequence.
Note: A[i] <= 105 

Examples: 

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: a[] = {3, 5, 6, 12, 15, 36} 
Output
The longest subsequence is {3, 6, 12, 36} 
6 = 3*2 
12 = 6*2 
36 = 12*3 
2 and 3 are primes 



Input: a[] = {1, 2, 5, 6, 12, 35, 60, 385} 
Output: 5  

Approach: The problem can be solved using pre-storing primes till the largest number in the array and using basic Dynamic Programming. The following steps can be followed to solve the above problem:  

  • Initially, they store all the primes in any of the data structures.
  • Hash the index of the numbers in a hash-map.
  • Create a dp[] of size N, and initialize it with 1 at every place, as the longest subsequence possible is 1 only. dp[i] represents the length of the longest subsequence that can be formed with a[i] as the starting element.
  • Iterate from n-2, and for every number multiply it with all the primes till it exceeds a[n-1] and performs the operations below.
  • Multiply the number a[i] with prime to get x. If x exists in the hash-map then the recurrence will be dp[i] = max(dp[i], 1 + dp[hash[x]]).
  • In the end, iterate in dp[] array and find the maximum value which will be our answer.

Below is the implementation of the above approach: 

C++




// C++ program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to pre-store primes
void SieveOfEratosthenes(int MAX, vector<int>& primes)
{
    bool prime[MAX + 1];
    memset(prime, true, sizeof(prime));
 
    // Sieve method to check if prime or not
    for (long long p = 2; p * p <= MAX; p++) {
        if (prime[p] == true) {
            // Multiples
            for (long long i = p * p; i <= MAX; i += p)
                prime[i] = false;
        }
    }
 
    // Pre-store all the primes
    for (long long i = 2; i <= MAX; i++) {
        if (prime[i])
            primes.push_back(i);
    }
}
 
// Function to find the longest subsequence
int findLongest(int A[], int n)
{
    // Hash map
    unordered_map<int, int> mpp;
    vector<int> primes;
 
    // Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
 
    int dp[n];
    memset(dp, 0, sizeof dp);
 
    // Initialize last element with 1
    // as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
 
    // Iterate from the back and find the longest
    for (int i = n - 2; i >= 0; i--) {
 
        // Get the number
        int num = A[i];
 
        // Initialize dp[i] as 1
        // as the element will only me in
        // the subsequence .
        dp[i] = 1;
        int maxi = 0;
 
        // Iterate in all the primes and
        // multiply to get the next element
        for (auto it : primes) {
 
            // Next element if multiplied with it
            int xx = num * it;
 
            // If exceeds the last element
            // then break
            if (xx > A[n - 1])
                break;
 
            // If the number is there in the array
            else if (mpp[xx] != 0) {
                // Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
            }
        }
        // Hash the element
        mpp[A[i]] = i;
    }
    int ans = 1;
 
    // Find the longest
    for (int i = 0; i < n; i++) {
        ans = max(ans, dp[i]);
    }
 
    return ans;
}
// Driver Code
int main()
{
    int a[] = { 1, 2, 5, 6, 12, 35, 60, 385 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << findLongest(a, n);
}

Java




// Java program to implement the
// above approach
import java.util.HashMap;
import java.util.Vector;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                            Vector<Integer> primes)
    {
        boolean[] prime = new boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        HashMap<Integer, Integer> mpp = new HashMap<>();
        Vector<Integer> primes = new Vector<>();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.put(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
            int maxi = 0;
 
            // Iterate in all the primes and
            // multiply to get the next element
            for (int it : primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.get(xx) != null && mpp.get(xx) != 0)
                {
 
                        // Get the maximum most element
                        dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
                }
            }
 
            // Hash the element
            mpp.put(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.length;
        System.out.println(findLongest(a, n));
 
    }
}
 
// This code is contributed by
// sanjeev2552

Python3




# Python3 program to implement the
# above approach
 
from math import sqrt
 
# Function to pre-store primes
def SieveOfEratosthenes(MAX, primes) :
 
    prime = [True]*(MAX + 1);
 
    # Sieve method to check if prime or not
    for p in range(2,int(sqrt(MAX)) + 1) :
        if (prime[p] == True) :
            # Multiples
            for i in range(p**2, MAX + 1, p) :
                prime[i] = False;
 
    # Pre-store all the primes
    for i in range(2, MAX + 1) :
        if (prime[i]) :
            primes.append(i);
 
# Function to find the longest subsequence
def findLongest(A, n) :
 
    # Hash map
    mpp = {};
    primes = [];
     
    # Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
     
    dp = [0] * n ;
     
    # Initialize last element with 1
    # as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
     
    # Iterate from the back and find the longest
    for i in range(n-2,-1,-1) :
         
        # Get the number
        num = A[i];
         
        # Initialize dp[i] as 1
        # as the element will only me in
        # the subsequence
        dp[i] = 1;
        maxi = 0;
         
        # Iterate in all the primes and
        # multiply to get the next element
        for it in primes :
             
            # Next element if multiplied with it
            xx = num * it;
             
            # If exceeds the last element
            # then break
            if (xx > A[n - 1]) :
                break;
                 
            # If the number is there in the array
            elif xx in mpp :
                # Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
                 
        # Hash the element
        mpp[A[i]] = i;
         
    ans = 1;
         
    # Find the longest
    for i in range(n) :
        ans = max(ans, dp[i]);
         
    return ans;
 
# Driver Code
if __name__ == "__main__" :
 
    a = [ 1, 2, 5, 6, 12, 35, 60, 385 ];
    n = len(a);
     
    print(findLongest(a, n));
 
# This code is contributed by AnkitRai01

C#




// C# program to implement the
// above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                                      List<int> primes)
    {
        Boolean[] prime = new Boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.Add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        Dictionary<int, int> mpp = new Dictionary<int, int>();
        List<int> primes = new List<int>();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.Add(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
 
            // Iterate in all the primes and
            // multiply to get the next element
            foreach (int it in primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.ContainsKey(xx) && mpp[xx] != 0)
                {
 
                    // Get the maximum most element
                    dp[i] = Math.Max(dp[i], 1 + dp[mpp[xx]]);
                }
            }
 
            // Hash the element
            if(mpp.ContainsKey(A[i]))
                mpp[A[i]] = i;
            else
                mpp.Add(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.Max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.Length;
        Console.WriteLine(findLongest(a, n));
    }
}
 
// This code is contributed by Rajput-Ji

Javascript




<script>
    // Javascript program to implement the
    // above approach
 
 
    // Function to pre-store primes
    function SieveOfEratosthenes(MAX, primes) {
        let prime = new Array(MAX + 1).fill(true);
 
 
        // Sieve method to check if prime or not
        for (let p = 2; p * p <= MAX; p++) {
            if (prime[p] == true) {
            // Multiples
                for (let i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (let i = 2; i <= MAX; i++) {
            if (prime[i])
                primes.push(i);
        }
    }   
 
    // Function to find the longest subsequence
    function findLongest(A, n) {
        // Hash map
        let mpp = new Map();
        let primes = new Array();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        let dp = new Array(n);
        dp.fill(0)
 
        // Initialize last element with 1
        // as that is the longest possible
        dp[n - 1] = 1;
        mpp.set(A[n - 1], n - 1);
 
        // Iterate from the back and find the longest
        for (let i = n - 2; i >= 0; i--) {
 
            // Get the number
            let num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
            let maxi = 0;
 
            // Iterate in all the primes and
            // multiply to get the next element
            for (let it of primes) {
 
                // Next element if multiplied with it
                let xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.get(xx)) {
                    // Get the maximum most element
                    dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
                }
            }
            // Hash the element
            mpp.set(A[i], i);
        }
        let ans = 1;
 
        // Find the longest
        for (let i = 0; i < n; i++) {
            ans = Math.max(ans, dp[i]);
        }
 
        return ans;
    }
    // Driver Code
 
    let a = [1, 2, 5, 6, 12, 35, 60, 385];
    let n = a.length;
    document.write(findLongest(a, n));
 
 
// This code is contributed by _saurabh_jaiswal
</script>
Output: 
5

 

Time Complexity: O(N log N) 
Auxiliary Space: O(N)
 




My Personal Notes arrow_drop_up
Recommended Articles
Page :