Related Articles
Length of longest increasing prime subsequence from a given array
• Last Updated : 17 Sep, 2020

Given an array arr[] consisting of N positive integers, the task is to find the length of the longest increasing subsequence consisting of Prime Numbers in the given array.

Examples:

Input: arr[] = {1, 2, 5, 3, 2, 5, 1, 7}
Output: 4
Explanation:
The Longest Increasing Prime Subsequence is {2, 3, 5, 7}.
Therefore, the answer is 4.

Input: arr[] = {6, 11, 7, 13, 9, 25}
Output: 2
Explanation:
The Longest Increasing Prime Subsequence is {11, 13} and {7, 13}.
Therefore, the answer is 2.

Naive Approach: The simplest approach is to generate all possible subsequence of the given array and print the length of the longest subsequence consisting of prime numbers in increasing order.

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

Efficient Approach: The idea is to use the Dynamic Programming approach to optimize the above approach. This problem is a basic variation of the Longest Increasing Subsequence (LIS) problem. Below are the steps:

• Initialize an auxiliary array dp[] of size N such that dp[i] will store the length of LIS of prime numbers ending at index i.
• Below is the recurrence relation for finding the longest increasing Prime Numbers:

If arr[i] is prime then
dp[i] = 1 + max(dp[j], for j belongs (0, i – 1)), where 0 < j < i and arr[j] < arr[i];
dp[i] = 1, if no such j exists
else if arr[i] is non-prime then
dp[i]  = 0

• Using Sieve of Eratosthenes store all the prime numbers to till 105.
• Iterate a two nested loop over the given array and update the array dp[] according to the above recurrence relation.
• After all the above steps, the maximum element in the array dp[] is the length of the longest increasing subsequence of Prime Numbers in the given array.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach`` ` `#include ``using` `namespace` `std;``#define N 100005`` ` `// Function to find the prime numbers``// till 10^5 using Sieve of Eratosthenes``void` `SieveOfEratosthenes(``bool` `prime[],``                         ``int` `p_size)``{``    ``// False here indicates``    ``// that it is not prime``    ``prime = ``false``;``    ``prime = ``false``;`` ` `    ``for` `(``int` `p = 2; p * p <= p_size; p++) {`` ` `        ``// If prime[p] is not changed,``        ``// then it is a prime``        ``if` `(prime[p]) {`` ` `            ``// Update all multiples of p,``            ``// set them to non-prime``            ``for` `(``int` `i = p * 2;``                 ``i <= p_size; i += p)``                ``prime[i] = ``false``;``        ``}``    ``}``}`` ` `// Function which computes the length``// of the LIS of Prime Numbers``int` `LISPrime(``int` `arr[], ``int` `n)``{``    ``// Create an array of size n``    ``int` `lisp[n];`` ` `    ``// Create boolean array to``    ``// mark prime numbers``    ``bool` `prime[N + 1];`` ` `    ``// Initialize all values to true``    ``memset``(prime, ``true``, ``sizeof``(prime));`` ` `    ``// Precompute N primes``    ``SieveOfEratosthenes(prime, N);`` ` `    ``lisp = prime[arr] ? 1 : 0;`` ` `    ``// Compute optimized LIS having``    ``// prime numbers in bottom up manner``    ``for` `(``int` `i = 1; i < n; i++) {``        ``if` `(!prime[arr[i]]) {``            ``lisp[i] = 0;``            ``continue``;``        ``}`` ` `        ``lisp[i] = 1;``        ``for` `(``int` `j = 0; j < i; j++) {`` ` `            ``// Check for LIS and prime``            ``if` `(prime[arr[j]]``                ``&& arr[i] > arr[j]``                ``&& lisp[i] < lisp[j] + 1) {``                ``lisp[i] = lisp[j] + 1;``            ``}``        ``}``    ``}`` ` `    ``// Return maximum value in lis[]``    ``return` `*max_element(lisp, lisp + n);``}`` ` `// Driver Code``int` `main()``{``    ``// Given array``    ``int` `arr[] = { 1, 2, 5, 3, 2, 5, 1, 7 };`` ` `    ``// Size of array``    ``int` `M = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``// Function Call``    ``cout << LISPrime(arr, M);`` ` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;`` ` `class` `GFG{``     ` `static` `final` `int` `N = ``100005``;`` ` `// Function to find the prime numbers``// till 10^5 using Sieve of Eratosthenes``static` `void` `SieveOfEratosthenes(``boolean` `prime[],``                                ``int` `p_size)``{``     ` `    ``// False here indicates``    ``// that it is not prime``    ``prime[``0``] = ``false``;``    ``prime[``1``] = ``false``;`` ` `    ``for``(``int` `p = ``2``; p * p <= p_size; p++) ``    ``{`` ` `        ``// If prime[p] is not changed,``        ``// then it is a prime``        ``if` `(prime[p]) ``        ``{`` ` `            ``// Update all multiples of p,``            ``// set them to non-prime``            ``for``(``int` `i = p * ``2``;``                    ``i <= p_size;``                    ``i += p)``                ``prime[i] = ``false``;``        ``}``    ``}``}`` ` `// Function which computes the length``// of the LIS of Prime Numbers``static` `int` `LISPrime(``int` `arr[], ``int` `n)``{``     ` `    ``// Create an array of size n``    ``int` `[]lisp = ``new` `int``[n];`` ` `    ``// Create boolean array to``    ``// mark prime numbers``    ``boolean` `[]prime = ``new` `boolean``[N + ``1``];`` ` `    ``// Initialize all values to true``    ``for``(``int` `i = ``0``; i < prime.length; i++)``        ``prime[i] = ``true``;`` ` `    ``// Precompute N primes``    ``SieveOfEratosthenes(prime, N);`` ` `    ``lisp[``0``] = prime[arr[``0``]] ? ``1` `: ``0``;`` ` `    ``// Compute optimized LIS having``    ``// prime numbers in bottom up manner``    ``for``(``int` `i = ``1``; i < n; i++)``    ``{``        ``if` `(!prime[arr[i]]) ``        ``{``            ``lisp[i] = ``0``;``            ``continue``;``        ``}`` ` `        ``lisp[i] = ``1``;``        ``for``(``int` `j = ``0``; j < i; j++) ``        ``{``             ` `            ``// Check for LIS and prime``            ``if` `(prime[arr[j]] && ``                ``arr[i] > arr[j] && ``               ``lisp[i] < lisp[j] + ``1``) ``            ``{``                ``lisp[i] = lisp[j] + ``1``;``            ``}``        ``}``    ``}`` ` `    ``// Return maximum value in lis[]``    ``return` `Arrays.stream(lisp).max().getAsInt();``}`` ` `// Driver Code``public` `static` `void` `main(String[] args)``{``     ` `    ``// Given array``    ``int` `arr[] = { ``1``, ``2``, ``5``, ``3``, ``2``, ``5``, ``1``, ``7` `};`` ` `    ``// Size of array``    ``int` `M = arr.length;`` ` `    ``// Function call``    ``System.out.print(LISPrime(arr, M));``}``}`` ` `// This code is contributed by Amit Katiyar`

## Python3

 `# Python3 program for ``# the above approach ``N ``=` `100005``  ` `# Function to find the prime numbers``# till 10^5 using Sieve of Eratosthenes``def` `SieveOfEratosthenes(prime, p_size):`` ` `  ``# False here indicates``  ``# that it is not prime``  ``prime[``0``] ``=` `False``  ``prime[``1``] ``=` `False`` ` `  ``p ``=` `2``  ``while` `p ``*` `p <``=` `p_size:`` ` `    ``# If prime[p] is not changed,``    ``# then it is a prime``    ``if` `(prime[p]):`` ` `      ``# Update all multiples of p,``      ``# set them to non-prime``      ``for` `i ``in` `range` `(p ``*` `2``,``                      ``p_size ``+` `1``, p):``        ``prime[i] ``=` `False`` ` `        ``p ``+``=` `1`` ` `# Function which computes the length``# of the LIS of Prime Numbers``def` `LISPrime(arr, n):`` ` `  ``# Create an array of size n``  ``lisp ``=` `[``0``] ``*` `n`` ` `  ``# Create boolean array to``  ``# mark prime numbers``  ``prime ``=` `[``True``] ``*` `(N ``+` `1``)`` ` `  ``# Precompute N primes``  ``SieveOfEratosthenes(prime, N)`` ` `  ``if` `prime[arr[``0``]]:``    ``lisp[``0``] ``=` `1``    ``else``:``      ``lisp[``0``] ``=` `0`` ` `      ``# Compute optimized LIS having``      ``# prime numbers in bottom up manner``      ``for` `i ``in` `range` `(``1``, n):``        ``if` `(``not` `prime[arr[i]]):``          ``lisp[i] ``=` `0``          ``continue`` ` `          ``lisp[i] ``=` `1``          ``for` `j ``in` `range` `(i):``            ``# check for LIS and prime``            ``if` `(prime[arr[j]] ``and` `                ``arr[i] > arr[j] ``and` `                ``lisp[i] < lisp[j] ``+` `1``):``              ``lisp[i] ``=` `lisp[j] ``+` `1`` ` `              ``# Return maximum value in lis[]``              ``return` `max``(lisp)`` ` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:`` ` `  ``# Given array``  ``arr ``=` `[``1``, ``2``, ``5``, ``3``, ``         ``2``, ``5``, ``1``, ``7``]`` ` `  ``# Size of array``  ``M ``=` `len``(arr)`` ` `  ``# Function Call``  ``print` `(LISPrime(arr, M))`` ` `# This code is contributed by Chitranayal`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Linq;`` ` `class` `GFG{``     ` `static` `readonly` `int` `N = 100005;`` ` `// Function to find the prime numbers``// till 10^5 using Sieve of Eratosthenes``static` `void` `SieveOfEratosthenes(``bool` `[]prime,``                                ``int` `p_size)``{``     ` `    ``// False here indicates``    ``// that it is not prime``    ``prime = ``false``;``    ``prime = ``false``;`` ` `    ``for``(``int` `p = 2; p * p <= p_size; p++) ``    ``{`` ` `        ``// If prime[p] is not changed,``        ``// then it is a prime``        ``if` `(prime[p]) ``        ``{`` ` `            ``// Update all multiples of p,``            ``// set them to non-prime``            ``for``(``int` `i = p * 2;``                    ``i <= p_size;``                    ``i += p)``                ``prime[i] = ``false``;``        ``}``    ``}``}`` ` `// Function which computes the length``// of the LIS of Prime Numbers``static` `int` `LISPrime(``int` `[]arr, ``int` `n)``{``     ` `    ``// Create an array of size n``    ``int` `[]lisp = ``new` `int``[n];`` ` `    ``// Create bool array to``    ``// mark prime numbers``    ``bool` `[]prime = ``new` `bool``[N + 1];`` ` `    ``// Initialize all values to true``    ``for``(``int` `i = 0; i < prime.Length; i++)``        ``prime[i] = ``true``;`` ` `    ``// Precompute N primes``    ``SieveOfEratosthenes(prime, N);`` ` `    ``lisp = prime[arr] ? 1 : 0;`` ` `    ``// Compute optimized LIS having``    ``// prime numbers in bottom up manner``    ``for``(``int` `i = 1; i < n; i++)``    ``{``        ``if` `(!prime[arr[i]]) ``        ``{``            ``lisp[i] = 0;``            ``continue``;``        ``}`` ` `        ``lisp[i] = 1;``        ``for``(``int` `j = 0; j < i; j++) ``        ``{``             ` `            ``// Check for LIS and prime``            ``if` `(prime[arr[j]] && ``                ``arr[i] > arr[j] && ``               ``lisp[i] < lisp[j] + 1) ``            ``{``                ``lisp[i] = lisp[j] + 1;``            ``}``        ``}``    ``}`` ` `    ``// Return maximum value in lis[]``    ``return` `lisp.Max();``}`` ` `// Driver Code``public` `static` `void` `Main(String[] args)``{``     ` `    ``// Given array``    ``int` `[]arr = { 1, 2, 5, 3, 2, 5, 1, 7 };`` ` `    ``// Size of array``    ``int` `M = arr.Length;`` ` `    ``// Function call``    ``Console.Write(LISPrime(arr, M));``}``}`` ` `// This code is contributed by Amit Katiyar `
Output:
```4
```

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

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up