Maximum subarray sum in O(n) using prefix sum
Given an Array of Positive and Negative Integers, find out the Maximum Subarray Sum in that Array.
Examples:
Input1 : arr = {-2, -3, 4, -1, -2, 1, 5, -3}
Output1 : 7
Input2 : arr = {4, -8, 9, -4, 1, -8, -1, 6}
Output2 : 9
Kadane’s Algorithm solves this problem using Dynamic Programming approach in linear time. Here is another approach using Dynamic Programming and Prefix Sum to find out maximum subarray sum in Linear time.
Prerequisite: Prefix Sum Array
- First calculate the prefix sum (prefix_sum) of the input array.
- Sum of a subarray from index x to y can be presented as,
- Now maximum of these subarrays is,
That is, we keep track of minimum prefix sum for x <= y and maximum subarray sum so far.
Implementation:
- Calculate the prefix sum of the input array.
- Initialize : min_prefix_sum = 0, res = -infinite
- Maintain a loop for i = 0 to n. (n is the size of the input array).
- cand = prefix_sum[i] – mini
- If cand is greater than res (maximum subarray sum so far), then update res by cand.
- If prefix_sum[i] is less than min_prefix_sum (minimum prefix sum so far), then update min_prefix_sum by prefix_sum[i].
- Return res.
C++
#include <iostream>
#include <limits>
using namespace std;
int maximumSumSubarray( int arr[], int n)
{
int min_prefix_sum = 0;
int res = numeric_limits< int >::min();
int prefix_sum[n];
prefix_sum[0] = arr[0];
for ( int i = 1; i < n; i++)
prefix_sum[i] = prefix_sum[i - 1] + arr[i];
for ( int i = 0; i < n; i++) {
res = max(res, prefix_sum[i] -
min_prefix_sum);
min_prefix_sum = min(min_prefix_sum,
prefix_sum[i]);
}
return res;
}
int main()
{
int arr1[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
int n1 = sizeof (arr1) / sizeof (arr1[0]);
cout << maximumSumSubarray(arr1, n1) << endl;
int arr2[] = { 4, -8, 9, -4, 1, -8, -1, 6 };
int n2 = sizeof (arr2) / sizeof (arr2[0]);
cout << maximumSumSubarray(arr2, n2);
return 0;
}
|
Java
class GFG
{
static int maximumSumSubarray( int arr[], int n)
{
int min_prefix_sum = 0 ;
int res = Integer.MIN_VALUE;
int prefix_sum[] = new int [n];
prefix_sum[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
prefix_sum[i] = prefix_sum[i - 1 ]
+ arr[i];
for ( int i = 0 ; i < n; i++)
{
res = Math.max(res, prefix_sum[i] -
min_prefix_sum);
min_prefix_sum = Math.min(min_prefix_sum,
prefix_sum[i]);
}
return res;
}
public static void main (String[] args)
{
int arr1[] = { - 2 , - 3 , 4 , - 1 , - 2 , 1 , 5 , - 3 };
int n1 = arr1.length;
System.out.println(maximumSumSubarray(arr1, n1));
int arr2[] = { 4 , - 8 , 9 , - 4 , 1 , - 8 , - 1 , 6 };
int n2 = arr2.length;
System.out.println(maximumSumSubarray(arr2, n2));
}
}
|
Python3
import math
def maximumSumSubarray(arr, n):
min_prefix_sum = 0
res = - math.inf
prefix_sum = []
prefix_sum.append(arr[ 0 ])
for i in range ( 1 , n):
prefix_sum.append(prefix_sum[i - 1 ] + arr[i])
for i in range (n):
res = max (res, prefix_sum[i] - min_prefix_sum)
min_prefix_sum = min (min_prefix_sum, prefix_sum[i])
return res
arr1 = [ - 2 , - 3 , 4 , - 1 , - 2 , 1 , 5 , - 3 ]
n1 = len (arr1)
print (maximumSumSubarray(arr1, n1))
arr2 = [ 4 , - 8 , 9 , - 4 , 1 , - 8 , - 1 , 6 ]
n2 = len (arr2)
print (maximumSumSubarray(arr2, n2))
|
C#
using System;
class GFG
{
static int maximumSumSubarray( int []arr, int n)
{
int min_prefix_sum = 0;
int res = int .MinValue;
int []prefix_sum = new int [n];
prefix_sum[0] = arr[0];
for ( int i = 1; i < n; i++)
prefix_sum[i] = prefix_sum[i - 1]
+ arr[i];
for ( int i = 0; i < n; i++)
{
res = Math.Max(res, prefix_sum[i] -
min_prefix_sum);
min_prefix_sum = Math.Min(min_prefix_sum,
prefix_sum[i]);
}
return res;
}
public static void Main ()
{
int []arr1 = { -2, -3, 4, -1, -2, 1, 5, -3 };
int n1 = arr1.Length;
Console.WriteLine(maximumSumSubarray(arr1, n1));
int []arr2 = { 4, -8, 9, -4, 1, -8, -1, 6 };
int n2 = arr2.Length;
Console.WriteLine(maximumSumSubarray(arr2, n2));
}
}
|
PHP
<?php
function maximumSumSubarray( $arr , $n )
{
$min_prefix_sum = 0;
$res = PHP_INT_MIN;
$prefix_sum = array ();
$prefix_sum [0] = $arr [0];
for ( $i = 1; $i < $n ; $i ++)
$prefix_sum [ $i ] = $prefix_sum [ $i - 1] +
$arr [ $i ];
for ( $i = 0; $i < $n ; $i ++)
{
$res = max( $res , $prefix_sum [ $i ] -
$min_prefix_sum );
$min_prefix_sum = min( $min_prefix_sum ,
$prefix_sum [ $i ]);
}
return $res ;
}
$arr1 = array (-2, -3, 4, -1,
-2, 1, 5, -3);
$n1 = count ( $arr1 );
echo maximumSumSubarray( $arr1 , $n1 ), " \n" ;
$arr2 = array (4, -8, 9, -4,
1, -8, -1, 6);
$n2 = count ( $arr2 );
echo maximumSumSubarray( $arr2 , $n2 );
?>
|
Javascript
<script>
function maximumSumSubarray(arr, n)
{
let min_prefix_sum = 0;
let res = Number.MIN_VALUE;
let prefix_sum = [];
prefix_sum[0] = arr[0];
for (let i = 1; i < n; i++)
prefix_sum[i] = prefix_sum[i - 1]
+ arr[i];
for (let i = 0; i < n; i++)
{
res = Math.max(res, prefix_sum[i] -
min_prefix_sum);
min_prefix_sum = Math.min(min_prefix_sum,
prefix_sum[i]);
}
return res;
}
let arr1 = [ -2, -3, 4, -1, -2, 1, 5, -3 ];
let n1 = arr1.length;
document.write(maximumSumSubarray(arr1, n1) + "<br/>" );
let arr2 = [ 4, -8, 9, -4, 1, -8, -1, 6 ];
let n2 = arr2.length;
document.write(maximumSumSubarray(arr2, n2));
</script>
|
Simpler and Efficient Solution
Time Complexity: O(n). It takes linear time to compute the prefix sum and takes constant time in each iteration of the for loop.
Auxiliary Space: O(n)
Please note that the above problem can be solved in O(n) time and O(1) extra space using Kadane’s algorithm
Last Updated :
12 Oct, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...