Given an array ‘arr’ of length ‘n’. The task is to find the largest contiguous sub-array having the count of prime numbers strictly greater than the count of non-prime numbers.
Examples:
Input: arr[] = {4, 7, 4, 7, 11, 5, 4, 4, 4, 5} Output: 9 Input: arr[] = { 1, 9, 3, 4, 5, 6, 7, 8 } Output: 5
Approach: To find the largest subarray in which count of prime is strictly greater than the count of non-prime:
First of all, use sieve to find the prime number.
Replace all primes with 1 in the array and all non-primes with -1. Now this problem is similar to Longest subarray having count of 1s one more than count of 0s
Below is the implementation of the above approach:
// C++ implementation of above approach #include <bits/stdc++.h> using namespace std;
bool prime[1000000 + 5];
void findPrime()
{ memset (prime, true , sizeof (prime));
prime[1] = false ;
for ( int p = 2; p * p <= 1000000; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true ) {
// Update all multiples of p
for ( int i = p * 2; i <= 1000000; i += p)
prime[i] = false ;
}
}
} // Function to find the length of longest // subarray having count of primes more // than count of non-primes int lenOfLongSubarr( int arr[], int n)
{ // unordered_map 'um' implemented as
// hash table
unordered_map< int , int > um;
int sum = 0, maxLen = 0;
// traverse the given array
for ( int i = 0; i < n; i++) {
// consider -1 as non primes and 1 as primes
sum += prime[arr[i]] == 0 ? -1 : 1;
// when subarray starts form index '0'
if (sum == 1)
maxLen = i + 1;
// make an entry for 'sum' if it is
// not present in 'um'
else if (um.find(sum) == um.end())
um[sum] = i;
// check if 'sum-1' is present in 'um'
// or not
if (um.find(sum - 1) != um.end()) {
// update maxLength
if (maxLen < (i - um[sum - 1]))
maxLen = i - um[sum - 1];
}
}
// required maximum length
return maxLen;
} // Driver code int main()
{ findPrime();
int arr[] = { 1, 9, 3, 4, 5, 6, 7, 8 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << lenOfLongSubarr(arr, n) << endl;
return 0;
} |
// Java implementation of above approach import java.util.*;
class GfG {
static boolean prime[] = new boolean [ 1000000 + 5 ];
static void findPrime()
{
Arrays.fill(prime, true );
prime[ 1 ] = false ;
for ( int p = 2 ; p * p <= 1000000 ; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true ) {
// Update all multiples of p
for ( int i = p * 2 ; i <= 1000000 ; i += p)
prime[i] = false ;
}
}
}
// Function to find the length of longest
// subarray having count of primes more
// than count of non-primes
static int lenOfLongSubarr( int arr[], int n)
{
// unordered_map 'um' implemented as
// hash table
Map<Integer, Integer> um = new HashMap<Integer, Integer>();
int sum = 0 , maxLen = 0 ;
// traverse the given array
for ( int i = 0 ; i < n; i++) {
// consider -1 as non primes and 1 as primes
sum += prime[arr[i]] == false ? - 1 : 1 ;
// when subarray starts form index '0'
if (sum == 1 )
maxLen = i + 1 ;
// make an entry for 'sum' if it is
// not present in 'um'
else if (!um.containsKey(sum))
um.put(sum, i);
// check if 'sum-1' is present in 'um'
// or not
if (um.containsKey(sum - 1 )) {
// update maxLength
if (maxLen < (i - um.get(sum - 1 )))
maxLen = i - um.get(sum - 1 );
}
}
// required maximum length
return maxLen;
}
// Driver code
public static void main(String[] args)
{
findPrime();
int arr[] = { 1 , 9 , 3 , 4 , 5 , 6 , 7 , 8 };
int n = arr.length;
System.out.println(lenOfLongSubarr(arr, n));
}
} |
# Python3 implementation of above approach prime = [ True ] * ( 1000000 + 5 )
def findPrime():
prime[ 0 ], prime[ 1 ] = False , False
for p in range ( 2 , 1001 ):
# If prime[p] is not changed,
# then it is a prime
if prime[p] = = True :
# Update all multiples of p
for i in range (p * 2 , 1000001 , p):
prime[i] = False
# Function to find the length of longest # subarray having count of primes more # than count of non-primes def lenOfLongSubarr(arr, n):
# unordered_map 'um' implemented as
# hash table
um = {}
Sum , maxLen = 0 , 0
# traverse the given array
for i in range ( 0 , n):
# consider -1 as non primes and 1 as primes
Sum = Sum - 1 if prime[arr[i]] = = False else Sum + 1
# when subarray starts form index '0'
if Sum = = 1 :
maxLen = i + 1
# make an entry for 'sum' if
# it is not present in 'um'
elif Sum not in um:
um[ Sum ] = i
# check if 'sum-1' is present
# in 'um' or not
if ( Sum - 1 ) in um:
# update maxLength
if maxLen < (i - um[ Sum - 1 ]):
maxLen = i - um[ Sum - 1 ]
# required maximum length
return maxLen
# Driver Code if __name__ = = "__main__" :
findPrime()
arr = [ 1 , 9 , 3 , 4 , 5 , 6 , 7 , 8 ]
n = len (arr)
print (lenOfLongSubarr(arr, n))
# This code is contributed # by Rituraj Jain |
// C# implementation of above approach using System;
using System.Collections.Generic;
class GfG {
static bool [] prime = new bool [1000000 + 5];
static void findPrime()
{
Array.Fill(prime, true );
prime[1] = false ;
for ( int p = 2; p * p <= 1000000; p++) {
// If prime[p] is not changed,
// then it is a prime
if (prime[p] == true ) {
// Update all multiples of p
for ( int i = p * 2; i <= 1000000; i += p)
prime[i] = false ;
}
}
}
// Function to find the length of longest
// subarray having count of primes more
// than count of non-primes
static int lenOfLongSubarr( int [] arr, int n)
{
// unordered_map 'um' implemented as
// hash table
Dictionary< int , int > um = new Dictionary< int , int >();
int sum = 0, maxLen = 0;
// traverse the given array
for ( int i = 0; i < n; i++) {
// consider -1 as non primes and 1 as primes
sum += prime[arr[i]] == false ? -1 : 1;
// when subarray starts form index '0'
if (sum == 1)
maxLen = i + 1;
// make an entry for 'sum' if it is
// not present in 'um'
else if (!um.ContainsKey(sum))
um[sum] = i;
// check if 'sum-1' is present in 'um'
// or not
if (um.ContainsKey(sum - 1)) {
// update maxLength
if (maxLen < (i - um[sum - 1]))
maxLen = i - um[sum - 1];
}
}
// required maximum length
return maxLen;
}
// Driver code
public static void Main()
{
findPrime();
int [] arr = { 1, 9, 3, 4, 5, 6, 7, 8 };
int n = arr.Length;
Console.WriteLine(lenOfLongSubarr(arr, n));
}
} // This code is contributed by Code_Mech. |
<script> // Javascript implementation of above approach let prime = new Array(1000000 + 5);
function findPrime() {
prime.fill( true )
prime[1] = false ;
for (let p = 2; p * p <= 1000000; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true ) {
// Update all multiples of p
for (let i = p * 2; i <= 1000000; i += p)
prime[i] = false ;
}
}
} // Function to find the length of longest // subarray having count of primes more // than count of non-primes function lenOfLongSubarr(arr, n) {
// unordered_map 'um' implemented as
// hash table
let um = new Map();
let sum = 0, maxLen = 0;
// traverse the given array
for (let i = 0; i < n; i++) {
// consider -1 as non primes and 1 as primes
sum += prime[arr[i]] == 0 ? -1 : 1;
// when subarray starts form index '0'
if (sum == 1)
maxLen = i + 1;
// make an entry for 'sum' if it is
// not present in 'um'
else if (!um.has(sum))
um.set(sum, i);
// check if 'sum-1' is present in 'um'
// or not
if (um.has(sum - 1)) {
// update maxLength
if (maxLen < (i - um.get(sum - 1)))
maxLen = i - um.get(sum - 1);
}
}
// required maximum length
return maxLen;
} // Driver code findPrime(); let arr = [1, 9, 3, 4, 5, 6, 7, 8]; let n = arr.length; document.write(lenOfLongSubarr(arr, n) + "<br>" )
// This code is contributed by Saurabh Jaiswal </script> |
5
Time Complexity: O(P*log(log(P)) + N), where P is the upper range up to which prime numbers are needed to be calculated during preprocessing and N is the length of the given array.
Auxiliary Space: O(P + N), where P is the hardcoded length of the prime array (1000000 + 5).