Maximize the size of array by deleting exactly k sub-arrays to make array prime

Given an array arr[] of N positive integers and a non-negative integer K. The task is to delete exactly K sub-arrays from the array such that all the remaining elements of the array are prime and the size of the remaining array is maximum possible.
Examples:Â
Input: arr[] = {2, 4, 2, 2, 4, 2, 4, 2}, k = 2Â
Output: 4Â
Delete the subarrays arr[1] and arr[4…6] andÂ
the remaining prime array will be {2, 2, 2, 2}Input: arr[] = {2, 4, 2, 2, 4, 2, 4, 2}, k = 3Â
Output: 5Â
A simple approach would be to search for all the sub-arrays that would cost us O(N2) time complexity and then keep track of the number of primes or composites in a particular length of sub-array.
An efficient approach is to keep track of the number of primes between two consecutive composites.
- Preprocessing step: Store all the primes in the prime array using Sieve of Eratosthenes
- Compute the indices of all composite numbers in a vector v.
- Compute the distance between two consecutive indices of the above-described vector in a vector diff as this will store the number of primes between any two consecutive composites.
- Sort this vector. After sorting, we get the subarray that contains the least no of primes to the highest no of primes.
- Compute the prefix sum of this vector. Now each index of diff denotes the k value and the value in diff denotes no of primes to be deleted when deleting k subarrays. 0th index denotes the largest k less than the size of v, 1st index denotes the second-largest k, and so on. So, from the prefix sum vector, we directly get the no of primes to be deleted.
After performing the above steps, our solution depends on three cases:Â
- This is an impossible case if k is 0 and there are composite integers in the array.
- If k is greater than or equal to no of composites, then we can delete all-composite integers and extra primes to equate the value k. These all subarrays are of size 1 which gives us the optimal answers.
- If k is less than no of composite integers, then we have to delete those subarrays which contain all the composite and no of primes falling into those subarrays.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;const int N = 1e7 + 5;bool prime[N];Â
// Sieve of Eratosthenesvoid sieve(){Â Â Â Â for (int i = 2; i < N; i++) {Â Â Â Â Â Â Â Â if (!prime[i]) {Â Â Â Â Â Â Â Â Â Â Â Â for (int j = i + i; j < N; j += i) {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prime[j] = 1;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }Â Â Â Â prime[1] = 1;}Â
// Function to return the size// of the maximized arrayint maxSizeArr(int* arr, int n, int k){Â Â Â Â vector<int> v, diff;Â
    // Insert the indices of composite numbers    for (int i = 0; i < n; i++) {        if (prime[arr[i]])            v.push_back(i);    }Â
    // Compute the number of prime between    // two consecutive composite    for (int i = 1; i < v.size(); i++) {        diff.push_back(v[i] - v[i - 1] - 1);    }Â
    // Sort the diff vector    sort(diff.begin(), diff.end());Â
    // Compute the prefix sum of diff vector    for (int i = 1; i < diff.size(); i++) {        diff[i] += diff[i - 1];    }Â
    // Impossible case    if (k > n || (k == 0 && v.size())) {        return -1;    }Â
    // Delete sub-arrays of length 1    else if (v.size() <= k) {        return (n - k);    }Â
    // Find the number of primes to be deleted    // when deleting the sub-arrays    else if (v.size() > k) {        int tt = v.size() - k;        int sum = 0;        sum += diff[tt - 1];        int res = n - (v.size() + sum);        return res;    }}Â
// Driver codeint main(){Â Â Â Â sieve();Â Â Â Â int arr[] = { 2, 4, 2, 2, 4, 2, 4, 2 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â Â Â Â int k = 2;Â Â Â Â cout << maxSizeArr(arr, n, k);Â
    return 0;} |
Java
// Java implementation of the approachimport java.util.*;Â
class GFG{Â
static int N = 10000005;static int []prime = new int[N];Â
// Sieve of Eratosthenesstatic void sieve(){Â Â Â Â for (int i = 2; i < N; i++) Â Â Â Â {Â Â Â Â Â Â Â Â if (prime[i] == 0) Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â for (int j = i + i; j < N; j += i)Â Â Â Â Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prime[j] = 1;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }Â Â Â Â prime[1] = 1;}Â
// Function to return the size// of the maximized arraystatic int maxSizeArr(int arr[], int n, int k){Â Â Â Â ArrayList<Integer> v = new ArrayList<Integer>(); Â Â Â Â ArrayList<Integer> diff = new ArrayList<Integer>(); Â
    // Insert the indices of composite numbers    int num = 0;    for (int i = 0; i < n; i++)    {        if (prime[arr[i]] == 1)        {            v.add(i);        }    }Â
    // Compute the number of prime between    // two consecutive composite    num = 0;    for (int i = 1; i < v.size(); i++)    {        diff.add(v.get(i) - v.get(i - 1) - 1);    }Â
    // Sort the diff vector    Collections.sort(diff);Â
    // Compute the prefix sum of diff vector    for (int i = 1; i < diff.size(); i++)    {        diff.set(i, diff.get(i) + diff.get(i - 1));    }Â
    // Impossible case    if (k > n || (k == 0 && v.size() > 0))    {        return -1;    }Â
    // Delete sub-arrays of length 1    else if (v.size() <= k)     {        return (n - k);    }Â
    // Find the number of primes to be deleted    // when deleting the sub-arrays    else if (v.size() > k)    {        int tt = v.size() - k;        int sum = 0;        sum += diff.get(tt - 1);        int res = n - (v.size() + sum);        return res;    }    return 1;}     // Driver codepublic static void main(String []args){    sieve();    int []arr = { 2, 4, 2, 2, 4, 2, 4, 2 };    int n = arr.length;    int k = 2;    System.out.println(maxSizeArr(arr, n, k));}}Â
// This code is contributed by Surendra_Gangwar |
Python3
# Python implementation of above approachÂ
N = 10000005prime = [False]*NÂ
# Sieve of Eratosthenesdef sieve():    for i in range(2,N):        if not prime[i]:            for j in range(i+1,N):                prime[j] = True         prime[1] = TrueÂ
# Function to return the size# of the maximized arraydef maxSizeArr(arr, n, k):Â Â Â Â v, diff = [], []Â
    # Insert the indices of composite numbers    for i in range(n):        if prime[arr[i]]:            v.append(i)         # Compute the number of prime between    # two consecutive composite    for i in range(1, len(v)):        diff.append(v[i] - v[i-1] -1)         # Sort the diff vector    diff.sort()Â
    # Compute the prefix sum of diff vector    for i in range(1, len(diff)):        diff[i] += diff[i-1]         # Impossible case    if k > n or (k == 0 and len(v)):        return -1         # Delete sub-arrays of length 1    elif len(v) <= k:        return (n-k)         # Find the number of primes to be deleted    # when deleting the sub-arrays    elif len(v) > k:        tt = len(v) - k        s = 0        s += diff[tt-1]        res = n - (len(v) + s)        return resÂ
Â
# Driver codeif __name__ == "__main__":Â Â Â Â Â Â Â Â Â sieve()Â
    arr = [2, 4, 2, 2, 4, 2, 4, 2]    n = len(arr)    k = 2Â
    print(maxSizeArr(arr, n, k)) Â
# This code is contributed by# sanjeev2552 |
C#
// C# implementation of the approachusing System;using System.Collections.Generic;Â
class GFG{Â
static int N = 1000005;static int []prime = new int[N];Â
// Sieve of Eratosthenesstatic void sieve(){Â Â Â Â for(int i = 2; i < N; i++) Â Â Â Â {Â Â Â Â Â Â Â Â if (prime[i] == 0) Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â for(int j = i + i; Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â j < N; j += i)Â Â Â Â Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prime[j] = 1;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }Â Â Â Â prime[1] = 1;}Â
// Function to return the size// of the maximized arraystatic int maxSizeArr(int []arr, int n,                                 int k){    List<int> v = new List<int>();     List<int> diff = new List<int>(); Â
    // Insert the indices of composite numbers    //int num = 0;         for(int i = 0; i < n; i++)    {        if (prime[arr[i]] == 1)        {            v.Add(i);        }    }Â
    // Compute the number of prime between    // two consecutive composite    //num = 0;    for(int i = 1; i < v.Count; i++)    {        diff.Add(v[i] - v[i - 1] - 1);    }Â
    // Sort the diff vector    diff.Sort();Â
    // Compute the prefix sum of diff vector    for(int i = 1; i < diff.Count; i++)    {        diff[i] = diff[i] + diff[i - 1];     }Â
    // Impossible case    if (k > n || (k == 0 && v.Count > 0))    {        return -1;    }Â
    // Delete sub-arrays of length 1    else if (v.Count <= k)     {        return (n - k);    }Â
    // Find the number of primes to be deleted    // when deleting the sub-arrays    else if (v.Count > k)    {        int tt = v.Count - k;        int sum = 0;        sum += diff[tt - 1];        int res = n - (v.Count + sum);        return res;    }    return 1;}     // Driver codepublic static void Main(String []args){    sieve();    int []arr = { 2, 4, 2, 2, 4, 2, 4, 2 };    int n = arr.Length;    int k = 2;         Console.WriteLine(maxSizeArr(arr, n, k));}}Â
// This code is contributed by Amit Katiyar |
Javascript
<script>// Javascript implementation of the approachÂ
Â
const N = 1e7 + 5;let prime = new Array(N);Â
// Sieve of Eratosthenesfunction sieve() {Â Â Â Â for (let i = 2; i < N; i++) {Â Â Â Â Â Â Â Â if (!prime[i]) {Â Â Â Â Â Â Â Â Â Â Â Â for (let j = i + i; j < N; j += i) {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prime[j] = 1;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }Â Â Â Â prime[1] = 1;}Â
// Function to return the size// of the maximized arrayfunction maxSizeArr(arr, n, k) {Â Â Â Â let v = new Array();Â Â Â Â let diff = new Array();Â
    // Insert the indices of composite numbers    for (let i = 0; i < n; i++) {        if (prime[arr[i]])            v.push(i);    }Â
    // Compute the number of prime between    // two consecutive composite    for (let i = 1; i < v.length; i++) {        diff.push(v[i] - v[i - 1] - 1);    }Â
    // Sort the diff vector    diff.sort((a, b) => a - b);Â
    // Compute the prefix sum of diff vector    for (let i = 1; i < diff.length; i++) {        diff[i] += diff[i - 1];    }Â
    // Impossible case    if (k > n || (k == 0 && v.length)) {        return -1;    }Â
    // Delete sub-arrays of length 1    else if (v.length <= k) {        return (n - k);    }Â
    // Find the number of primes to be deleted    // when deleting the sub-arrays    else if (v.length > k) {        let tt = v.length - k;        let sum = 0;        sum += diff[tt - 1];        let res = n - (v.length + sum);        return res;    }}Â
// Driver codeÂ
sieve();let arr = [2, 4, 2, 2, 4, 2, 4, 2];let n = arr.length;let k = 2;document.write(maxSizeArr(arr, n, k));Â
// This code is contributed by _saurabh_jaiswalÂ
</script> |
4
Â
Time Complexity: O(N*logN), as we are using a inbuilt sort function to sort an array of size N. Where N is the number of elements in the array.
Auxiliary Space: O(10000005), as we using extra space for the prime array.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



