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 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 <bits/stdc++.h>

**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;

}

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 DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

#arrays #greedy #mathematical #prime number #sieve #subarray #two-pointer-algorithm

Length of longest subarray having only K distinct Prime Numbers
4.25 GEEK