This is one popular interview question. The problem: given an array which could contain zero, negative, and positive numbers, find the largest sum of contiguous sub-array. For example, if the array contains:
31, -41, 59, 26, -53, 58, 97, -93, -23, 84
then the largest sum is 187 taken from the [59 .. 97] block
My research points to Jon Bentley’s solution as the most efficient solution (see his book, “Programming Pearls”). In fact, Bentley was probably the person who started this thread. His solution has a complexity of O(n) which is very good, considering the brute force solution is of O(n3). Here is a Python implementation of Bentley’s solution:
def largest(array):
maxSoFar = maxUpToHere = 0
for element in array:
maxUpToHere= max(maxUpToHere + element, 0)
maxSoFar = max(maxSoFar, maxUpToHere)
return maxSoFar
This solution is very efficient, short, and easy to remember. To understand it, I recommend reading his book, “Programming Pearls.”
After implementing this solution, I wrote some test cases to verify its correctness. Overall, the code works well, but it does not return the correct value for cases when the whole array contains only negative numbers. For example, consider this array:
-3, -1, -2
I expect to see -1 as the largest sum, but instead, I got 0. After studying the algorithm, I noticed that the problem comes from the line:
maxUpToHere= max(maxUpToHere + element, 0)
For negatives-only cases, maxUpToHere will be zero because it is the larger of the two. Instead of zero, the correct output in these cases should be the largest number in the array. I also noticed that negatives-only are the only cases which cause trouble, so we can add detection to the code and return the largest element instead of maxSoFar. Here is the patched code:
# This is based on Bentley’s Programming Pearls
# My (Hai Vu’s) modification: if the array is all negatives
# then max is the largest element
def largest(array):
maxSoFar = maxUpToHere = 0
largestElement = array[0]
allNegatives = True
for element in array:
maxUpToHere= max(maxUpToHere + element, 0)
maxSoFar = max(maxSoFar, maxUpToHere)
largestElement = max(largestElement, element)
if element >= 0:
allNegatives = False
if allNegatives:
return largestElement
return maxSoFar
The patched code works well for all cases. However, if you have a better solution, I would like to learn about it. My python program is available for download: largestsumpy.pdf

This is great catch. Thanks for the patch. God bless Bentley
Comment by Abhi — February 6, 2008 @ 12:55 am
In C#.net (with finding the first and last elements of the array)
int[] i = {31, -41, 59, 26, -53, 58, 97, -93, -23, 84};
int maxSoFar = 0;
int maxUpToHere = 0;
int itr = 0;
int startIndex = 0;
int endIndex = 0;
int countStart = -1;
foreach (int n in i)
{
//maxUpToHere = (maxUpToHere + n > 0 ? maxUpToHere + n : 0);
//maxSoFar = (maxSoFar > maxUpToHere ? maxSoFar : maxUpToHere);
if ((maxUpToHere + n) > 0)
{
maxUpToHere += n;
countStart++;
}
else
{
maxUpToHere = 0;
countStart = -1;
}
if (countStart == 0)
{
startIndex = itr;
}
if (maxSoFar < maxUpToHere)
{
maxSoFar = maxUpToHere;
endIndex = itr;
}
itr++;
}
this.richTextBox1.Text = “Max so far: ” + maxSoFar.ToString() + “\nStartIndex: ” + startIndex.ToString()+”\nEndIndex: “+ endIndex.ToString() ;
Comment by hp7500 — April 11, 2008 @ 2:25 am
Why is a zero length sub-array not considered a sub-array?
Comment by recursive — April 14, 2008 @ 8:36 pm
Dear recursive,
If we take zero-length sub-array, then Bentley’s original solution is correct, even for negative-only cases.
Comment by wuhrr — April 15, 2008 @ 1:40 pm
int FindMaxSumSubArray(int* data, int length)
{
int max = 0;
int sum = 0;
for(int i=length-1; i>=0; i–)
{
sum += data[i];
if(sum max)
{
max = sum;
}
}
// all negative
if(max == 0)
{
max = data[0];
for(int i=1; i max) max = data[i];
}
}
return max;
}
Comment by sad — July 13, 2008 @ 9:27 pm
#include
#include
//Program to print the largest subarray sum and the indexes of the subarray
void main()
{
int maxuptohere=0,maxsofar=0,arr[5]={84,20,-50,-50,-60};
clrscr();
int allneg=1,maxelem=arr[0],start=-1,end=-1,indx=0;
for(int i=0;i=0?(start=(start==-1)?i:start),maxuptohere+arr[i]:0;
maxsofar=maxuptohere>=maxsofar?(end=i),(start=(maxuptohere==arr[i])?i:start),maxuptohere:maxsofar;
maxelem=maxelem>arr[i]?indx=i,arr[i]:maxelem;
if(arr[i]>=0)
allneg=0;
}
if(allneg)
start=end=indx;
printf(“Ans: %d %d %d”,allneg==1?maxelem:maxsofar,start,end);
}
Comment by amateurcoder — July 25, 2009 @ 12:56 pm
I really like this solution, but just to be picky, there’s no need to maintain an allNegatives variable. Just check to see if the largestElement is negative after iterating through the list. No biggie, but does eliminate n comparisons.
Comment by Jack — September 20, 2009 @ 8:17 pm