Maximum Subarray sum of Prime length
Last Updated :
24 Jan, 2023
Given an array arr[] of size N, the task is to find the maximum subarray sum that can be obtained such that the length of the subarray should be prime.
Examples :
Input: arr[] = {2, -1, 3, -2, 1, -1}
Output: 4
The subarray {2, -1, 3} of size = 3 (prime number)
input: arr[] = {-2, -3, 4, -1, -2, 1, 5, -3}
Output: 7
The subarray {4, -1, -2, 1, 5} of size = 5 (prime number)
Naive Approach: The idea is as follows:
Generate all possible subarrays and from them find the ones with prime length. Find the maximum sum among them.
Follow the given steps to solve the problem:
- Generate all possible subarrays of all lengths using nested for-loops.
- Find the sum of each prime length subarray.
- The numbers which are primes can be precomputed by Sieve algorithm
- Now for each prime length, calculate the sum and take the maximum of it
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
void sieve( int N, vector< bool >& prime)
{
prime[1] = false ;
prime[0] = false ;
for ( int i = 2; i * i <= N; i++) {
if (prime[i]) {
for ( int p = i * i; p <= N; p += i) {
prime[p] = false ;
}
}
}
}
int primeLenSum( int a[], int N)
{
vector< bool > prime(N + 1, true );
sieve(N, prime);
int ans = INT_MIN;
for ( int i = 0; i < N; i++) {
for ( int j = i + 1; j < N; j++) {
if (prime[j - i]) {
int sum = 0;
for ( int k = i; k <= j; k++)
sum += a[k];
ans = max(ans, sum);
}
}
}
return ans;
}
int main()
{
int arr[] = { 2, -1, 3, -2, 1, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << primeLenSum(arr, N) << "\n" ;
return 0;
}
|
Java
import java.io.*;
class GFG {
static boolean [] sieve( int N, boolean [] prime)
{
prime[ 1 ] = false ;
prime[ 0 ] = false ;
for ( int i = 2 ; i * i <= N; i++) {
if (prime[i]) {
for ( int p = i * i; p <= N; p += i) {
prime[p] = false ;
}
}
}
return prime;
}
static int primeLenSum( int [] a, int N)
{
boolean [] prime = new boolean [N + 1 ];
for ( int i = 0 ; i < N; i++) {
prime[i] = true ;
}
prime = sieve(N, prime);
int ans = Integer.MIN_VALUE;
for ( int i = 0 ; i < N; i++) {
for ( int j = i + 1 ; j < N; j++) {
if (prime[j - i]) {
int sum = 0 ;
for ( int k = i; k <= j; k++) {
sum += a[k];
}
ans = Math.max(ans, sum);
}
}
}
return ans;
}
public static void main(String[] args)
{
int [] arr = { 2 , - 1 , 3 , - 2 , 1 , - 1 };
int N = arr.length;
System.out.print(primeLenSum(arr, N));
}
}
|
Python3
import sys
def sieve(N, prime):
prime[ 1 ] = False
prime[ 0 ] = False
for i in range ( 2 ,N + 1 ):
if i * i< = N:
if (prime[i]):
for p in range (i * i,N + 1 ):
prime[p] = False
p + = i
def primeLenSum(a,N):
prime = [ True for i in range (N + 1 )]
sieve(N, prime)
ans = - sys.maxsize - 1
for i in range (N):
for j in range (i + 1 ,N):
if (prime[j - i]):
sum = 0
for k in range (i,j + 1 ):
sum + = a[k]
ans = max (ans, sum );
return ans
if __name__ = = '__main__' :
arr = [ 2 , - 1 , 3 , - 2 , 1 , - 1 ]
N = len (arr)
print ( primeLenSum(arr, N))
|
C#
using System;
public class GFG {
static bool [] sieve( int N, bool [] prime)
{
prime[1] = false ;
prime[0] = false ;
for ( int i = 2; i * i <= N; i++) {
if (prime[i]) {
for ( int p = i * i; p <= N; p += i) {
prime[p] = false ;
}
}
}
return prime;
}
static int primeLenSum( int [] a, int N)
{
bool [] prime = new bool [N + 1];
for ( int i = 0; i < N; i++) {
prime[i] = true ;
}
prime = sieve(N, prime);
int ans = Int32.MinValue;
for ( int i = 0; i < N; i++) {
for ( int j = i + 1; j < N; j++) {
if (prime[j - i]) {
int sum = 0;
for ( int k = i; k <= j; k++) {
sum += a[k];
}
ans = Math.Max(ans, sum);
}
}
}
return ans;
}
static public void Main()
{
int [] arr = { 2, -1, 3, -2, 1, -1 };
int N = arr.Length;
Console.Write(primeLenSum(arr, N));
}
}
|
Javascript
function sieve(N, prime) {
prime[1] = false ;
prime[0] = false ;
for (let i = 2; i * i <= N; i++) {
if (prime[i]) {
for (let p = i * i; p <= N; p += i) {
prime[p] = false ;
}
}
}
}
function primeLenSum(a, N) {
let prime = new Array(N + 1).fill( true );
sieve(N, prime);
let ans = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
if (prime[j - i]) {
let sum = 0;
for (let k = i; k <= j; k++) sum += a[k];
ans = Math.max(ans, sum);
}
}
}
return ans;
}
let arr = [2, -1, 3, -2, 1, -1];
let N = arr.length;
console.log(primeLenSum(arr, N));
|
Time complexity: O(N3)
Auxiliary Space: O(N)
Efficient Approach: To solve the problem follow the below idea:
Use Kadane’s algorithm, and update the answer only if the length of the subarray is prime.
Follow the given steps to solve the problem:
- Initialize max_so_far = INT_MIN (since sum can be negative), and max_ending_here = 0 (to keep track of the current sum )
- Loop to iterate each element of the array:
- max_ending_here is equal to max_ending_here + arr[i]
- If max_so_far is less than max_ending_here then update max_so_far
- If max_ending_here is less than 0 then set max_ending_here = 0
- Return max_so_far
- Now for calculating the subarray sum of prime length we have to keep track of the subarray size and have to check whether the size is prime or not
Below is the implementation of the above idea :
C++14
#include <bits/stdc++.h>
using namespace std;
void sieve( int n, vector< bool >& prime)
{
prime[1] = false ;
prime[0] = false ;
for ( int i = 2; i * i <= n; i++) {
if (prime[i]) {
for ( int p = i * i; p <= n; p += i) {
prime[p] = false ;
}
}
}
}
int primeLenSum( int a[], int N)
{
vector< bool > prime(N + 1, true );
sieve(N, prime);
int max_ending_here = 0;
int max_for_primes = 0, sz = 0;
for ( int i = 0; i < N; i++) {
max_ending_here += a[i];
sz = sz + 1;
if (max_ending_here < 0) {
max_ending_here = 0;
sz = 0;
}
if (max_ending_here > max_for_primes && prime[sz])
max_for_primes = max_ending_here;
}
return max_for_primes;
}
int main()
{
int arr[] = { 2, -1, 3, -2, 1, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << primeLenSum(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static boolean [] sieve( int n, boolean [] prime)
{
prime[ 1 ] = false ;
prime[ 0 ] = false ;
for ( int i = 2 ; i * i <= n; i++) {
if (prime[i]) {
for ( int p = i * i; p <= n; p += i) {
prime[p] = false ;
}
}
}
return prime;
}
static int primeLenSum( int [] a, int N)
{
boolean [] prime = new boolean [N + 1 ];
Arrays.fill(prime, true );
prime = sieve(N, prime);
int max_ending_here = 0 ;
int max_for_primes = 0 , sz = 0 ;
for ( int i = 0 ; i < N; i++) {
max_ending_here += a[i];
sz = sz + 1 ;
if (max_ending_here < 0 ) {
max_ending_here = 0 ;
sz = 0 ;
}
if (max_ending_here > max_for_primes
&& prime[sz]) {
max_for_primes = max_ending_here;
}
}
return max_for_primes;
}
public static void main(String[] args)
{
int [] arr = { 2 , - 1 , 3 , - 2 , 1 , - 1 };
int N = arr.length;
System.out.print(primeLenSum(arr, N));
}
}
|
Python3
def sieve(n, prime):
prime[ 1 ] = False
prime[ 0 ] = False
for i in range ( 2 , int (n * * ( 1 / 2 )) + 1 ):
if prime[i]:
for p in range (i * i, n + 1 , i):
prime[p] = False
def primeLenSum(a, N):
prime = [ True ] * (N + 1 )
sieve(N, prime)
max_ending_here = 0
max_for_primes = 0
sz = 0
for i in range (N):
max_ending_here + = a[i]
sz = sz + 1
if max_ending_here < 0 :
max_ending_here = 0
sz = 0
if max_ending_here > max_for_primes and prime[sz]:
max_for_primes = max_ending_here
return max_for_primes
arr = [ 2 , - 1 , 3 , - 2 , 1 , - 1 ]
N = len (arr)
print (primeLenSum(arr, N))
|
C#
using System;
using System.Collections.Generic;
public class Gfg {
static void sieve( int n, int [] prime)
{
prime[1] = 0;
prime[0] = 0;
for ( int i = 2; i * i <= n; i++) {
if (prime[i]==1) {
for ( int p = i * i; p <= n; p += i) {
prime[p] = 0;
}
}
}
}
static int primeLenSum( int []a, int N)
{
int [] prime = new int [N+1];
for ( int i=0; i<N+1; i++)
prime[i]=1;
sieve(N, prime);
int max_ending_here = 0;
int max_for_primes = 0, sz = 0;
for ( int i = 0; i < N; i++) {
max_ending_here += a[i];
sz = sz + 1;
if (max_ending_here < 0) {
max_ending_here = 0;
sz = 0;
}
if (max_ending_here > max_for_primes && prime[sz]==1)
max_for_primes = max_ending_here;
}
return max_for_primes;
}
public static void Main( string [] args)
{
int [] arr = { 2, -1, 3, -2, 1, -1 };
int N = arr.Length;
Console.WriteLine(primeLenSum(arr, N));
}
}
|
Javascript
function sieve(n, prime) {
prime[1] = false ;
prime[0] = false ;
for (let i = 2; i * i <= n; i++) {
if (prime[i]) {
for (let p = i * i; p <= n; p += i) {
prime[p] = false ;
}
}
}
}
function primeLenSum(a, N) {
const prime = Array(N + 1).fill( true );
sieve(N, prime);
let max_ending_here = 0;
let max_for_primes = 0,
sz = 0;
for (let i = 0; i < N; i++) {
max_ending_here += a[i];
sz = sz + 1;
if (max_ending_here < 0) {
max_ending_here = 0;
sz = 0;
}
if (max_ending_here > max_for_primes && prime[sz])
max_for_primes = max_ending_here;
}
return max_for_primes;
}
const arr = [2, -1, 3, -2, 1, -1];
const N = arr.length;
console.log(primeLenSum(arr, N));
|
Time Complexity: O(N * log(logN))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...