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:
Below is the implementation of the above approach:
// 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