Related Articles
Length of longest subarray having only K distinct Prime Numbers
• Last Updated : 07 Sep, 2020

Given an array arr[] consisting of N positive integers. The task is to find the length of the longest subarray of this array that contains exactly K distinct Prime Numbers. If there doesn’t exist any subarray then print “-1”.

Examples:

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, K = 1
Output: 4
Explanation:
The subarray {6, 7, 8, 9} contains 4 elements and only one is prime (7). Therefore, the required length is 4.

Input: arr[] = {1, 2, 3, 3, 4, 5, 6, 7, 8, 9}, K = 3
Output: 8
Explanation:
The subarray {3, 3, 4, 5, 6, 7, 8, 9} contains 8 elements and contains only 3 distinct primes(3, 5, and 7). Therefore, the required length is 8.

Naive Approach: The idea is to generate all possible subarray and check if any subarray with maximum length contains K distinct primes. If yes then print that length of the subarray else print “-1”.
Time Complexity: O(N2), where N is the length of the given array.
Space Complexity: O(N)

Efficient Approach: The idea is to use the Sieve of Eratosthenes to calculate the prime numbers and Two Pointer Technique to solve the above problem. Below are the steps:

1. Pre-calculate whether the given number is prime or not using the Sieve of Eratosthenes.
2. Maintain the count of primes occurring in the given array while traversing it.
3. Until K is not zero, we count the distinct prime occurring in the subarray and decrease K by 1.
4. As K becomes negative, start deleting the elements till the first prime number of the current subarray as there might be a possibility of a longer subarray afterward.
5. When K is 0, we update the maximum length.
6. Print the maximum length after all the above steps.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;``bool` `isprime[2000010];` `// Function to precalculate all the``// prime up to 10^6``void` `SieveOfEratosthenes(``int` `n)``{``    ``// Initialize prime to true``    ``memset``(isprime, ``true``, ``sizeof``(isprime));` `    ``isprime[1] = ``false``;` `    ``// Iterate [2, sqrt(N)]``    ``for` `(``int` `p = 2; p * p <= n; p++) {` `        ``// If p is prime``        ``if` `(isprime[p] == ``true``) {` `            ``// Mark all multiple of p as true``            ``for` `(``int` `i = p * p; i <= n; i += p)``                ``isprime[i] = ``false``;``        ``}``    ``}``}` `// Function that finds the length of``// longest subarray K distinct primes``int` `KDistinctPrime(``int` `arr[], ``int` `n,``                   ``int` `k)``{``    ``// Precompute all prime up to 2*10^6``    ``SieveOfEratosthenes(2000000);` `    ``// Keep track ocurrence of prime``    ``map<``int``, ``int``> cnt;` `    ``// Initialize result to -1``    ``int` `result = -1;` `    ``for` `(``int` `i = 0, j = -1; i < n; ++i) {` `        ``int` `x = arr[i];` `        ``// If number is prime then``        ``// increment its count and``        ``// decrease k``        ``if` `(isprime[x]) {` `            ``if` `(++cnt[x] == 1) {` `                ``// Decrement K``                ``--k;``            ``}``        ``}` `        ``// Remove required elements``        ``// till k become non-negative``        ``while` `(k < 0) {` `            ``x = arr[++j];``            ``if` `(isprime[x]) {` `                ``// Decrease count so``                ``// that it may appear``                ``// in another subarray``                ``// appearing after this``                ``// present subarray``                ``if` `(--cnt[x] == 0) {` `                    ``// Increment K``                    ``++k;``                ``}``            ``}``        ``}` `        ``// Take the max value as``        ``// length of subarray``        ``if` `(k == 0)``            ``result = max(result, i - j);``    ``}` `    ``// Return the final length``    ``return` `result;``}` `// Driver Code``int` `main(``void``)``{``    ``// Given array arr[]``    ``int` `arr[] = { 1, 2, 3, 3, 4,``                  ``5, 6, 7, 8, 9 };``    ``int` `K = 3;` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Function Call``    ``cout << KDistinctPrime(arr, N, K);``    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;``import` `java.lang.*;` `class` `GFG{` `static` `boolean``[] isprime = ``new` `boolean``[``2000010``];` `// Function to precalculate all the``// prime up to 10^6``static` `void` `SieveOfEratosthenes(``int` `n)``{``    ` `    ``// Initialize prime to true``    ``Arrays.fill(isprime, ``true``);` `    ``isprime[``1``] = ``false``;` `    ``// Iterate [2, sqrt(N)]``    ``for``(``int` `p = ``2``; p * p <= n; p++)``    ``{``        ` `        ``// If p is prime``        ``if` `(isprime[p] == ``true``)``        ``{``            ` `            ``// Mark all multiple of p as true``            ``for``(``int` `i = p * p; i <= n; i += p)``                ``isprime[i] = ``false``;``        ``}``    ``}``}` `// Function that finds the length of``// longest subarray K distinct primes``static` `int` `KDistinctPrime(``int` `arr[], ``int` `n,``                                     ``int` `k)``{``    ` `    ``// Precompute all prime up to 2*10^6``    ``SieveOfEratosthenes(``2000000``);` `    ``// Keep track ocurrence of prime``    ``Map cnt = ``new` `HashMap<>();` `    ``// Initialize result to -1``    ``int` `result = -``1``;` `    ``for``(``int` `i = ``0``, j = -``1``; i < n; ++i)``    ``{``        ``int` `x = arr[i];` `        ``// If number is prime then``        ``// increment its count and``        ``// decrease k``        ``if` `(isprime[x])``        ``{``            ``cnt.put(x, cnt.getOrDefault(x, ``0``) + ``1``);``            ` `            ``if` `(cnt.get(x) == ``1``)``            ``{``                ` `                ``// Decrement K``                ``--k;``            ``}``        ``}` `        ``// Remove required elements``        ``// till k become non-negative``        ``while` `(k < ``0``)``        ``{``            ``x = arr[++j];``            ``if` `(isprime[x])``            ``{``                ` `                ``// Decrease count so``                ``// that it may appear``                ``// in another subarray``                ``// appearing after this``                ``// present subarray``                ``cnt.put(x, cnt.getOrDefault(x, ``0``) - ``1``);``                ``if` `(cnt.get(x) == ``0``)``                ``{``                    ` `                    ``// Increment K``                    ``++k;``                ``}``            ``}``        ``}` `        ``// Take the max value as``        ``// length of subarray``        ``if` `(k == ``0``)``            ``result = Math.max(result, i - j);``    ``}` `    ``// Return the final length``    ``return` `result;``}` `// Driver Code``public` `static` `void` `main (String[] args)``{``    ` `    ``// Given array arr[]``    ``int` `arr[] = { ``1``, ``2``, ``3``, ``3``, ``4``,``                  ``5``, ``6``, ``7``, ``8``, ``9` `};``    ``int` `K = ``3``;``    ` `    ``int` `N = arr.length;``    ` `    ``// Function call``    ``System.out.println(KDistinctPrime(arr, N, K));``}``}` `// This code is contributed by offbeat`

## Python3

 `# Python3 program to implement``# the above approach``from` `collections ``import` `defaultdict` `isprime ``=` `[``True``] ``*` `2000010` `# Function to precalculate all the``# prime up to 10^6``def` `SieveOfEratosthenes(n):` `    ``isprime[``1``] ``=` `False` `    ``# Iterate [2, sqrt(N)]``    ``p ``=` `2``    ``while``(p ``*` `p <``=` `n):` `        ``# If p is prime``        ``if``(isprime[p] ``=``=` `True``):` `            ``# Mark all multiple of p as true``            ``for` `i ``in` `range``(p ``*` `p, n ``+` `1``, p):``                ``isprime[i] ``=` `False` `        ``p ``+``=` `1` `# Function that finds the length of``# longest subarray K distinct primes``def` `KDistinctPrime(arr, n, k):` `    ``# Precompute all prime up to 2*10^6``    ``SieveOfEratosthenes(``2000000``)` `    ``# Keep track ocurrence of prime``    ``cnt ``=` `defaultdict(``lambda` `: ``0``)` `    ``# Initialize result to -1``    ``result ``=` `-``1` `    ``j ``=` `-``1` `    ``for` `i ``in` `range``(n):``        ``x ``=` `arr[i]` `        ``# If number is prime then``        ``# increment its count and``        ``# decrease k``        ``if``(isprime[x]):``            ``cnt[x] ``+``=` `1` `            ``if``(cnt[x] ``=``=` `1``):` `                ``# Decrement K``                ``k ``-``=` `1` `    ``# Remove required elements``    ``# till k become non-negative``    ``while``(k < ``0``):``        ``j ``+``=` `1``        ``x ``=` `arr[j]``        ` `        ``if``(isprime[x]):` `            ``# Decrease count so``            ``# that it may appear``            ``# in another subarray``            ``# appearing after this``            ``# present subarray``            ``cnt[x] ``-``=` `1``            ``if``(cnt[x] ``=``=` `0``):` `                ``# Increment K``                ``k ``+``=` `1` `        ``# Take the max value as``        ``# length of subarray``        ``if``(k ``=``=` `0``):``            ``result ``=` `max``(result, i ``-` `j)` `    ``# Return the final length``    ``return` `result` `# Driver Code` `# Given array arr[]``arr ``=` `[ ``1``, ``2``, ``3``, ``3``, ``4``,``        ``5``, ``6``, ``7``, ``8``, ``9` `]` `K ``=` `3` `N ``=` `len``(arr)` `# Function call``print``(KDistinctPrime(arr, N, K))` `# This code is contributed by Shivam Singh`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;``class` `GFG{``static` `bool``[] isprime = ``new` `bool``[2000010];` `// Function to precalculate all the``// prime up to 10^6``static` `void` `SieveOfEratosthenes(``int` `n)``{   ``    ``// Initialize prime to true``    ``for``(``int` `i = 0; i < isprime.Length; i++)``        ``isprime[i] = ``true``;``    ``isprime[1] = ``false``;` `    ``// Iterate [2, sqrt(N)]``    ``for``(``int` `p = 2; p * p <= n; p++)``    ``{       ``        ``// If p is prime``        ``if` `(isprime[p] == ``true``)``        ``{           ``            ``// Mark all multiple of p as true``            ``for``(``int` `i = p * p; i <= n; i += p)``                ``isprime[i] = ``false``;``        ``}``    ``}``}` `// Function that finds the length of``// longest subarray K distinct primes``static` `int` `KDistinctPrime(``int` `[]arr,``                          ``int` `n, ``int` `k)``{   ``    ``// Precompute all prime up to 2*10^6``    ``SieveOfEratosthenes(2000000);` `    ``// Keep track ocurrence of prime``    ``Dictionary<``int``,``               ``int``> cnt = ``new` `Dictionary<``int``,``                                         ``int``>();` `    ``// Initialize result to -1``    ``int` `result = -1;` `    ``for``(``int` `i = 0, j = -1; i < n; ++i)``    ``{``        ``int` `x = arr[i];` `        ``// If number is prime then``        ``// increment its count and``        ``// decrease k``        ``if` `(isprime[x])``        ``{``            ``if``(cnt.ContainsKey(x))``                ``cnt[x] = cnt[x] + 1;``            ``else``                ``cnt.Add(x, 1);           ``            ``if` `(cnt[x] == 1)``            ``{               ``                ``// Decrement K``                ``--k;``            ``}``        ``}` `        ``// Remove required elements``        ``// till k become non-negative``        ``while` `(k < 0)``        ``{``            ``x = arr[++j];``            ``if` `(isprime[x])``            ``{               ``                ``// Decrease count so``                ``// that it may appear``                ``// in another subarray``                ``// appearing after this``                ``// present subarray``                ``if``(cnt.ContainsKey(x))``                    ``cnt[x] = cnt[x] - 1;``                ``else``                    ``cnt.Add(x, 0);``                ``if` `(cnt[x] == 0)``                ``{                   ``                    ``// Increment K``                    ``++k;``                ``}``            ``}``        ``}` `        ``// Take the max value as``        ``// length of subarray``        ``if` `(k == 0)``            ``result = Math.Max(result, i - j);``    ``}` `    ``// Return the readonly length``    ``return` `result;``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{   ``    ``// Given array []arr``    ``int` `[]arr = {1, 2, 3, 3, 4,``                 ``5, 6, 7, 8, 9};``    ``int` `K = 3;``    ` `    ``int` `N = arr.Length;``    ` `    ``// Function call``    ``Console.WriteLine(KDistinctPrime(arr, N, K));``}``}` `// This code is contributed by 29AjayKumar`
Output:
```8

```

Time Complexity: O(N*log(log(N))), where N is the maximum element in the given array.
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