Skip to content
Related Articles

Related Articles

Maximum sum of K-length subarray with maximum count of distinct prime factors
  • Difficulty Level : Medium
  • Last Updated : 12 Mar, 2021

Given an array arr[] consisting of N positive integers and an integer K, the task is to find the maximum sum of array elements in a subarray having maximum sum of distinct prime factors in each K-length subarray. 
Note: If there are multiple answers then print the sum of the original subarray having maximum sum.

Examples:

Input: arr[] = {1, 4, 2, 10, 3}, K = 3
Output: 16
Explanation: 
All possible subarrays of length 3 are:
{1, 4, 2} → having 0+1+1= 2 distinct prime factors
{4, 2, 10} → having 1+1+2= 4 distinct prime factors. Sum = 16.
{2, 10, 3} → having 1+1+2= 4 distinct prime factors. Sum = 15.
Therefore, maximum sum of K length subarrays with maximum distinct prime factors is 16.

Input: arr[] = {10, 14, 12, 9, 16, 11}, K = 2
Output: 26

Naive Approach: The simplest approach is to generate all possible subarrays of length K from the given array and traverse each subarray and count distinct prime factors of its elements and compute their sums. Finally, print the maximum sum among subarrays having maximum count of distinct prime factors.
Time Complexity: O(N3 * sqrt(MAX)), where MAX is the maximum number present in the array.
Auxiliary Space: O(N * sqrt(MAX))

Efficient Approach: The optimal idea is to use Sieve of Eratosthenes and Sliding window technique to solve this problem. Follow the steps below to solve the problem:

  • Initialize an array, say CountDsitinct[], to store the count of distinct prime factors up to a limit using sieve by incrementing the count of CountDistinct[] every time, while marking multiples of prime number as false.
  • The sum of a subarray (or window) of size K can be obtained in constant time using the sum of the previous subarray (or window) of size K using  Sliding window technique.
  • Traverse the array arr[] and check which subarray has the maximum sum of distinct prime numbers. 
  • Finally, print the sum of the subarray or the sum of the original array having the maximum count of prime factors.

Below is the implementation of the above approach:



C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
#define MAX 100001
 
// Function to print the sum of
// subarray of length K having
// maximum distinct prime factors
int maxSum(int arr[], int N, int K)
{
    // If K exceeds N
    if (N < K) {
        cout << "Invalid";
        return -1;
    }
 
    // Stores the count of distinct primes
    int CountDistinct[MAX + 1];
 
    // True, if index 'i' is a prime
    bool prime[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
        CountDistinct[i] = 0;
        prime[i] = true;
    }
 
    for (long long int i = 2; i <= MAX; i++) {
 
        // If i is prime
        if (prime[i] == true) {
 
            // Number is prime
            CountDistinct[i] = 1;
 
            // Count of factors of a prime number is 1
            for (long long int j = i * 2; j <= MAX;
                 j += i) {
 
                // Increment CountDistinct as
                // the factors of i
                CountDistinct[j]++;
 
                // Mark its multiple non-prime
                prime[j] = false;
            }
        }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
       
        Maxarr_sum += arr[i];
        DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
       
        curr_sum += CountDistinct[arr[i]]
                    - CountDistinct[arr[i - K]];
       
        curr_arrSum += arr[i] - arr[i - K];
        if (curr_sum > DistPrimeSum) {
           
            DistPrimeSum = curr_sum;
            Maxarr_sum = curr_arrSum;
        }
        else if (curr_sum == DistPrimeSum) {
           
            Maxarr_sum = max(
              curr_arrSum, Maxarr_sum);
        }
    }
 
    // Print the maximum sum
    cout << Maxarr_sum;
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    maxSum(arr, N, K);
 
    return 0;
}

Java




// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG
{
 
  static int MAX = 100001;
 
  // Function to print the sum of
  // subarray of length K having
  // maximum distinct prime factors
  static void maxSum(int arr[], int N, int K)
  {
 
    // If K exceeds N
    if (N < K) {
      System.out.println("Invalid");
      return;
    }
 
    // Stores the count of distinct primes
    int CountDistinct[] = new int[MAX + 1];
 
    // True, if index 'i' is a prime
    boolean prime[] = new boolean[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
      CountDistinct[i] = 0;
      prime[i] = true;
    }
 
    for (int i = 2; i <= MAX; i++) {
 
      // If i is prime
      if (prime[i] == true) {
 
        // Number is prime
        CountDistinct[i] = 1;
 
        // Count of factors of a prime number is 1
        for (int j = i * 2; j <= MAX; j += i) {
 
          // Increment CountDistinct as
          // the factors of i
          CountDistinct[j]++;
 
          // Mark its multiple non-prime
          prime[j] = false;
        }
      }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
 
      Maxarr_sum += arr[i];
      DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
 
      curr_sum += CountDistinct[arr[i]]
        - CountDistinct[arr[i - K]];
 
      curr_arrSum += arr[i] - arr[i - K];
      if (curr_sum > DistPrimeSum) {
 
        DistPrimeSum = curr_sum;
        Maxarr_sum = curr_arrSum;
      }
      else if (curr_sum == DistPrimeSum) {
 
        Maxarr_sum
          = Math.max(curr_arrSum, Maxarr_sum);
      }
    }
 
    // Print the maximum sum
    System.out.println(Maxarr_sum);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    // Given array
    int arr[] = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = arr.length;
 
    maxSum(arr, N, K);
  }
}
 
// This code is contributed by Kingash.

C#




// C# Program to implement
// the above approach
using System;
public class GFG
{
 
  static int MAX = 100001;
 
  // Function to print the sum of
  // subarray of length K having
  // maximum distinct prime factors
  static void maxSum(int []arr, int N, int K)
  {
 
    // If K exceeds N
    if (N < K) {
      Console.WriteLine("Invalid");
      return;
    }
 
    // Stores the count of distinct primes
    int []CountDistinct = new int[MAX + 1];
 
    // True, if index 'i' is a prime
    bool []prime = new bool[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
      CountDistinct[i] = 0;
      prime[i] = true;
    }
 
    for (int i = 2; i <= MAX; i++) {
 
      // If i is prime
      if (prime[i] == true) {
 
        // Number is prime
        CountDistinct[i] = 1;
 
        // Count of factors of a prime number is 1
        for (int j = i * 2; j <= MAX; j += i) {
 
          // Increment CountDistinct as
          // the factors of i
          CountDistinct[j]++;
 
          // Mark its multiple non-prime
          prime[j] = false;
        }
      }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
 
      Maxarr_sum += arr[i];
      DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
 
      curr_sum += CountDistinct[arr[i]]
        - CountDistinct[arr[i - K]];
 
      curr_arrSum += arr[i] - arr[i - K];
      if (curr_sum > DistPrimeSum) {
 
        DistPrimeSum = curr_sum;
        Maxarr_sum = curr_arrSum;
      }
      else if (curr_sum == DistPrimeSum) {
 
        Maxarr_sum
          = Math.Max(curr_arrSum, Maxarr_sum);
      }
    }
 
    // Print the maximum sum
    Console.WriteLine(Maxarr_sum);
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
 
    // Given array
    int []arr = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = arr.Length;
 
    maxSum(arr, N, K);
  }
}
 
// This code is contributed by 29AjayKumar

 
 

Output
16

 

Time Complexity: O(N * log N)
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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :