给定由N个正整数和整数K组成的数组arr [] ,任务是在每个K长度子数组中找到具有最大不同素数和的子数组中数组元素的最大和。
注意:如果有多个答案,则打印具有最大和的原始子数组的和。
例子:
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
天真的方法:最简单的方法是从给定的数组生成长度为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)