Longest sub-array of Prime Numbers using Segmented Sieve

Given an array arr[] of N integers, the task is to find the longest subarray where all numbers in that subarray are prime.

Examples:

Input: arr[] = {3, 5, 2, 66, 7, 11, 8}
Output: 3
Explanation:
Maximum contiguous prime number sequence is {2, 3, 5}

Input: arr[] = {1, 2, 11, 32, 8, 9}
Output: 2
Explanation:
Maximum contiguous prime number sequence is {2, 11}

Approach:
For elements of the array in order of 106, we have discussed an approach in this article.
For elements of the array in order of 109, the idea is to use Segmented Sieve to find the Prime Numbers to value upto 109.



Steps:

  1. Find the Prime Numbers between the range of minimum element and maximum element of the array using the approach discussed in this article.
  2. After calculating the Prime Numbers between the range. The longest subarray with Prime Numbers can be calculated using Kadane’s Algorithm. Following are the steps:
    • Traverse the given array arr[] with two variables named current_max and max_so_far.
    • If a Prime Number is found then increment current_max and compare it with max_so_far.
    • If current_max is greater than max_so_far, then update max_so_far to current_max.
    • If any element is non-prime element, then reset current_max to 0.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find longest subarray
// of prime numbers
#include <bits/stdc++.h>
using namespace std;
  
// To store the prime numbers
unordered_set<int> allPrimes;
  
// Function that find prime numbers
// till limit
void simpleSieve(int limit,
                 vector<int>& prime)
{
    bool mark[limit + 1];
    memset(mark, false, sizeof(mark));
  
    // Find primes using
    // Sieve of Eratosthenes
    for (int i = 2; i <= limit; ++i) {
        if (mark[i] == false) {
            prime.push_back(i);
            for (int j = i; j <= limit;
                 j += i) {
                mark[j] = true;
            }
        }
    }
}
  
// Function that finds all prime
// numbers in given range using
// Segmented Sieve
void primesInRange(int low, int high)
{
    // Find the limit
    int limit = floor(sqrt(high)) + 1;
  
    // To store the prime numbers
    vector<int> prime;
  
    // Comput all primes less than
    // or equals to sqrt(high)
    // using Simple Sieve
    simpleSieve(limit, prime);
  
    // Count the elements in the
    // range [low, high]
    int n = high - low + 1;
  
    // Declaring boolean for the
    // range [low, high]
    bool mark[n + 1];
  
    // Initialise bool[] to false
    memset(mark, false, sizeof(mark));
  
    // Traverse the prime numbers till
    // limit
    for (int i = 0; i < prime.size(); i++) {
  
        int loLim = floor(low / prime[i]);
            loLim
            *= prime[i];
  
        // Find the minimum number in
        // [low..high] that is a
        // multiple of prime[i]
        if (loLim < low) {
            loLim += prime[i];
        }
  
        if (loLim == prime[i]) {
            loLim += prime[i];
        }
  
        // Mark the multiples of prime[i]
        // in [low, high] as true
        for (int j = loLim; j <= high;
             j += prime[i])
            mark[j - low] = true;
    }
  
    // Element which are not marked in
    // range are Prime
    for (int i = low; i <= high; i++) {
        if (!mark[i - low]) {
            allPrimes.insert(i);
        }
    }
}
  
// Function that finds longest subarray
// of prime numbers
int maxPrimeSubarray(int arr[], int n)
{
    int current_max = 0;
    int max_so_far = 0;
  
    for (int i = 0; i < n; i++) {
  
        // If element is Non-prime then
        // updated current_max to 0
        if (!allPrimes.count(arr[i]))
            current_max = 0;
  
        // If element is prime, then
        // update current_max and
        // max_so_far
        else {
            current_max++;
            max_so_far = max(current_max,
                             max_so_far);
        }
    }
  
    // Return the count of longest
    // subarray
    return max_so_far;
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 2, 4, 3, 29,
                  11, 7, 8, 9 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Find minimum and maximum element
    int max_el = *max_element(arr, arr + n);
    int min_el = *min_element(arr, arr + n);
  
    // Find prime in the range
    // [min_el, max_el]
    primesInRange(min_el, max_el);
  
    // Function call
    cout << maxPrimeSubarray(arr, n);
    return 0;
}

chevron_right


Output:

4

Time Complexity: O(N), where N is the length of the array.
Auxillary Space: O(N), where N is the length of the array.

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.