📜  K长度子数组的最大和与不同素数的最大数量

📅  最后修改于: 2021-05-17 21:07:26             🧑  作者: Mango

给定由N个正整数和整数K组成的数组arr [] ,任务是在每个K长度子数组中找到具有最大不同素数和的子数组中数组元素的最大和。
注意:如果有多个答案,则打印具有最大和的原始子数组的和。

例子:

天真的方法:最简单的方法是从给定的数组生成长度为K的所有可能的子数组,并遍历每个子数组并计算其元素的不同素数并计算其和。最后,在最大数量的不同素因数的子阵列中打印最大和。
时间复杂度: O(N 3 * sqrt(MAX)),其中MAX是数组中存在的最大数目。
辅助空间: O(N * sqrt(MAX))

高效的方法:最佳方法是使用Eratosthenes筛和滑动窗口技术来解决此问题。请按照以下步骤解决问题:

  • 初始化一个数组,例如CountDsitinct [] ,通过每次增加CountDistinct []的计数,同时将素数的倍数标记为false ,使用筛子将不同素数的计数存储到一个上限。
  • 大小为K的子数组(或窗口)的总和可以使用滑动窗口技术使用大小为K的先前子数组(或窗口)的总和在恒定时间内获得。
  • 遍历数组arr []并检查哪个子数组具有最大不同质数的总和。  
  • 最后,打印子数组的总和或具有最大素数计数的原始数组的总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
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


输出
16

时间复杂度: O(N * log N)
辅助空间: O(N)