Length of longest subarray having only K distinct Prime Numbers
Last Updated :
13 Sep, 2023
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 the Two Pointer Technique to solve the above problem. Below are the steps:
- Pre-calculate whether the given number is prime or not using the Sieve of Eratosthenes.
- Maintain the count of primes occurring in the given array while traversing it.
- Until K is not zero, we count the distinct prime occurring in the subarray and decrease K by 1.
- 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.
- When K is 0, we update the maximum length.
- Print the maximum length after all the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool isprime[2000010];
void SieveOfEratosthenes( int n)
{
memset (isprime, true , sizeof (isprime));
isprime[1] = false ;
for ( int p = 2; p * p <= n; p++) {
if (isprime[p] == true ) {
for ( int i = p * p; i <= n; i += p)
isprime[i] = false ;
}
}
}
int KDistinctPrime( int arr[], int n,
int k)
{
SieveOfEratosthenes(2000000);
map< int , int > cnt;
int result = -1;
for ( int i = 0, j = -1; i < n; ++i) {
int x = arr[i];
if (isprime[x]) {
if (++cnt[x] == 1) {
--k;
}
}
while (k < 0) {
x = arr[++j];
if (isprime[x]) {
if (--cnt[x] == 0) {
++k;
}
}
}
if (k == 0)
result = max(result, i - j);
}
return result;
}
int main( void )
{
int arr[] = { 1, 2, 3, 3, 4,
5, 6, 7, 8, 9 };
int K = 3;
int N = sizeof (arr) / sizeof (arr[0]);
cout << KDistinctPrime(arr, N, K);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static boolean [] isprime = new boolean [ 2000010 ];
static void SieveOfEratosthenes( int n)
{
Arrays.fill(isprime, true );
isprime[ 1 ] = false ;
for ( int p = 2 ; p * p <= n; p++)
{
if (isprime[p] == true )
{
for ( int i = p * p; i <= n; i += p)
isprime[i] = false ;
}
}
}
static int KDistinctPrime( int arr[], int n,
int k)
{
SieveOfEratosthenes( 2000000 );
Map<Integer, Integer> cnt = new HashMap<>();
int result = - 1 ;
for ( int i = 0 , j = - 1 ; i < n; ++i)
{
int x = arr[i];
if (isprime[x])
{
cnt.put(x, cnt.getOrDefault(x, 0 ) + 1 );
if (cnt.get(x) == 1 )
{
--k;
}
}
while (k < 0 )
{
x = arr[++j];
if (isprime[x])
{
cnt.put(x, cnt.getOrDefault(x, 0 ) - 1 );
if (cnt.get(x) == 0 )
{
++k;
}
}
}
if (k == 0 )
result = Math.max(result, i - j);
}
return result;
}
public static void main (String[] args)
{
int arr[] = { 1 , 2 , 3 , 3 , 4 ,
5 , 6 , 7 , 8 , 9 };
int K = 3 ;
int N = arr.length;
System.out.println(KDistinctPrime(arr, N, K));
}
}
|
Python3
from collections import defaultdict
isprime = [ True ] * 2000010
def SieveOfEratosthenes(n):
isprime[ 1 ] = False
p = 2
while (p * p < = n):
if (isprime[p] = = True ):
for i in range (p * p, n + 1 , p):
isprime[i] = False
p + = 1
def KDistinctPrime(arr, n, k):
SieveOfEratosthenes( 2000000 )
cnt = defaultdict( lambda : 0 )
result = - 1
j = - 1
for i in range (n):
x = arr[i]
if (isprime[x]):
cnt[x] + = 1
if (cnt[x] = = 1 ):
k - = 1
while (k < 0 ):
j + = 1
x = arr[j]
if (isprime[x]):
cnt[x] - = 1
if (cnt[x] = = 0 ):
k + = 1
if (k = = 0 ):
result = max (result, i - j)
return result
arr = [ 1 , 2 , 3 , 3 , 4 ,
5 , 6 , 7 , 8 , 9 ]
K = 3
N = len (arr)
print (KDistinctPrime(arr, N, K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool [] isprime = new bool [2000010];
static void SieveOfEratosthenes( int n)
{
for ( int i = 0; i < isprime.Length; i++)
isprime[i] = true ;
isprime[1] = false ;
for ( int p = 2; p * p <= n; p++)
{
if (isprime[p] == true )
{
for ( int i = p * p; i <= n; i += p)
isprime[i] = false ;
}
}
}
static int KDistinctPrime( int []arr,
int n, int k)
{
SieveOfEratosthenes(2000000);
Dictionary< int ,
int > cnt = new Dictionary< int ,
int >();
int result = -1;
for ( int i = 0, j = -1; i < n; ++i)
{
int x = arr[i];
if (isprime[x])
{
if (cnt.ContainsKey(x))
cnt[x] = cnt[x] + 1;
else
cnt.Add(x, 1);
if (cnt[x] == 1)
{
--k;
}
}
while (k < 0)
{
x = arr[++j];
if (isprime[x])
{
if (cnt.ContainsKey(x))
cnt[x] = cnt[x] - 1;
else
cnt.Add(x, 0);
if (cnt[x] == 0)
{
++k;
}
}
}
if (k == 0)
result = Math.Max(result, i - j);
}
return result;
}
public static void Main(String[] args)
{
int []arr = {1, 2, 3, 3, 4,
5, 6, 7, 8, 9};
int K = 3;
int N = arr.Length;
Console.WriteLine(KDistinctPrime(arr, N, K));
}
}
|
Javascript
<script>
let isprime = new Array(2000010);
function SieveOfEratosthenes(n)
{
isprime.fill( true );
isprime[1] = false ;
for (let p = 2; p * p <= n; p++)
{
if (isprime[p] == true )
{
for (let i = p * p; i <= n; i += p)
isprime[i] = false ;
}
}
}
function KDistinctPrime(arr, n, k)
{
SieveOfEratosthenes(2000000);
let cnt = new Map();
let result = -1;
for (let i = 0, j = -1; i < n; ++i)
{
let x = arr[i];
if (isprime[x])
{
if (cnt.has(x))
cnt.set(x, cnt.get(x)+1)
else
cnt.set(x, 1);
if (cnt.get(x) == 1)
{
--k;
}
}
while (k < 0)
{
x = arr[++j];
if (isprime[x])
{
if (cnt.has(x))
cnt.set(x, cnt.get(x) - 1)
else
cnt.set(x, -1);
if (cnt.get(x) == 0)
{
++k;
}
}
}
if (k == 0)
result = Math.max(result, i - j);
}
return result;
}
let arr = [ 1, 2, 3, 3, 4, 5, 6, 7, 8, 9 ];
let K = 3;
let N = arr.length;
document.write(KDistinctPrime(arr, N, K));
</script>
|
Time Complexity: O(N*log(log(N))), where N is the maximum element in the given array.
Auxiliary Space: O(N)
Another Method (sliding window approach)
The task is to find the length of the longest subarray of this array can be found out using sliding window approach
Algorithm
- Initialize variables count, left, and max_len to 0
- Precompute all prime numbers up to the largest number in the array
- Iterate over each element in the array from left to right:
- If the current element is prime, increment the count of that prime in the count dictionary
- If the count of distinct primes in the count dictionary is greater than K, move the left pointer to the right until the count is less than or equal to K
- If the count of distinct primes in the count dictionary is equal to K, update max_len with the length of the current subarray (right – left + 1)
- Return max_len if it is greater than 0, Else return -1
C++
#include <bits/stdc++.h>
using namespace std;
bool isPrime( int n, const vector< int >& primes) {
for ( int p : primes) {
if (p * p > n)
break ;
if (n % p == 0)
return false ;
}
return n > 1;
}
int longestSubarrayWithKPrimes( const std::vector< int >& arr, int k) {
int limit = *std::max_element(arr.begin(), arr.end());
std::vector< int > primes;
for ( int p = 2; p <= limit; p++) {
if (isPrime(p, primes))
primes.push_back(p);
}
std::unordered_map< int , int > count;
int left = 0;
int maxLen = -1;
for ( int right = 0; right < arr.size(); right++) {
if (isPrime(arr[right], primes))
count[arr[right]] += 1;
while (count.size() > k) {
if (isPrime(arr[left], primes)) {
count[arr[left]] -= 1;
if (count[arr[left]] == 0)
count.erase(arr[left]);
}
left++;
}
if (count.size() == k)
maxLen = std::max(maxLen, right - left + 1);
}
return maxLen;
}
int main() {
vector< int > arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int k = 1;
cout << longestSubarrayWithKPrimes(arr, k) << endl;
arr = {1, 2, 3, 3, 4, 5, 6, 7, 8, 9};
k = 3;
cout << longestSubarrayWithKPrimes(arr, k) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static boolean isPrime( int n, List<Integer> primes) {
for ( int p : primes) {
if (p * p > n)
break ;
if (n % p == 0 )
return false ;
}
return n > 1 ;
}
static int longestSubarrayWithKPrimes(List<Integer> arr, int k) {
int limit = Collections.max(arr);
List<Integer> primes = new ArrayList<>();
for ( int p = 2 ; p <= limit; p++) {
if (isPrime(p, primes))
primes.add(p);
}
Map<Integer, Integer> count = new HashMap<>();
int left = 0 ;
int maxLen = - 1 ;
for ( int right = 0 ; right < arr.size(); right++) {
if (isPrime(arr.get(right), primes))
count.put(arr.get(right), count.getOrDefault(arr.get(right), 0 ) + 1 );
while (count.size() > k) {
if (isPrime(arr.get(left), primes)) {
count.put(arr.get(left), count.get(arr.get(left)) - 1 );
if (count.get(arr.get(left)) == 0 )
count.remove(arr.get(left));
}
left++;
}
if (count.size() == k)
maxLen = Math.max(maxLen, right - left + 1 );
}
return maxLen;
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 );
int k = 1 ;
System.out.println(longestSubarrayWithKPrimes(arr, k));
arr = Arrays.asList( 1 , 2 , 3 , 3 , 4 , 5 , 6 , 7 , 8 , 9 );
k = 3 ;
System.out.println(longestSubarrayWithKPrimes(arr, k));
}
}
|
Python3
def is_prime(n, primes):
for p in primes:
if p * p > n:
break
if n % p = = 0 :
return False
return n > 1
def longest_subarray_with_k_primes(arr, k):
limit = max (arr)
primes = [p for p in range ( 2 , limit + 1 ) if is_prime(p, primes = [])]
count = {}
left = 0
max_len = - 1
for right in range ( len (arr)):
if is_prime(arr[right], primes):
count[arr[right]] = count.get(arr[right], 0 ) + 1
while len (count) > k:
if is_prime(arr[left], primes):
count[arr[left]] - = 1
if count[arr[left]] = = 0 :
del count[arr[left]]
left + = 1
if len (count) = = k:
max_len = max (max_len, right - left + 1 )
return max_len
arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
k = 1
print (longest_subarray_with_k_primes(arr, k))
arr = [ 1 , 2 , 3 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
k = 3
print (longest_subarray_with_k_primes(arr, k))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static bool IsPrime( int n, List< int > primes)
{
foreach ( int p in primes)
{
if (p * p > n)
break ;
if (n % p == 0)
return false ;
}
return n > 1;
}
static int LongestSubarrayWithKPrimes(List< int > arr,
int k)
{
int limit = arr.Max();
List< int > primes = new List< int >();
for ( int p = 2; p <= limit; p++) {
if (IsPrime(p, primes))
primes.Add(p);
}
Dictionary< int , int > count
= new Dictionary< int , int >();
int left = 0;
int maxLen = -1;
for ( int right = 0; right < arr.Count; right++) {
if (IsPrime(arr[right], primes))
count[arr[right]]
= count.GetValueOrDefault(arr[right])
+ 1;
while (count.Count > k) {
if (IsPrime(arr[left], primes)) {
count[arr[left]] -= 1;
if (count[arr[left]] == 0)
count.Remove(arr[left]);
}
left++;
}
if (count.Count == k)
maxLen = Math.Max(maxLen, right - left + 1);
}
return maxLen;
}
static void Main()
{
List< int > arr
= new List< int >{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int k = 1;
Console.WriteLine(LongestSubarrayWithKPrimes(
arr, k));
arr = new List< int >{ 1, 2, 3, 3, 4, 5, 6, 7, 8, 9 };
k = 3;
Console.WriteLine(LongestSubarrayWithKPrimes(
arr, k));
}
}
|
Javascript
function isPrime(n, primes) {
for (let p of primes) {
if (p * p > n)
break ;
if (n % p === 0)
return false ;
}
return n > 1;
}
function longestSubarrayWithKPrimes(arr, k) {
let limit = Math.max(...arr);
let primes = [];
for (let p = 2; p <= limit; p++) {
if (isPrime(p, primes))
primes.push(p);
}
let count = new Map();
let left = 0;
let maxLen = -1;
for (let right = 0; right < arr.length; right++) {
if (isPrime(arr[right], primes)) {
if (!count.has(arr[right])) {
count.set(arr[right], 0);
}
count.set(arr[right], count.get(arr[right]) + 1);
}
while (count.size > k) {
if (isPrime(arr[left], primes)) {
count.set(arr[left], count.get(arr[left]) - 1);
if (count.get(arr[left]) === 0)
count. delete (arr[left]);
}
left++;
}
if (count.size === k)
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let k = 1;
console.log(longestSubarrayWithKPrimes(arr, k));
arr = [1, 2, 3, 3, 4, 5, 6, 7, 8, 9];
k = 3;
console.log(longestSubarrayWithKPrimes(arr, k));
|
Time Complexity: O(N * log(log(max(arr))) + N2), where N is the length of the input array and max(arr) is the maximum element in the array.
Space Complexity: O(max(arr)), due to the count dictionary used to store the count of each prime number in the subarray.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...