Reputation: 1731
I want to write a function ContigSum(i,j)
that calculates the sum of the contiguous elements a[i]
through a[j]
, where i<=j
and a[]
contains positive and negative numbers.
Could you please tell me a time efficient solution to find maximized contiguous SUM in the array?
Upvotes: 1
Views: 6652
Reputation: 1425
Here is my solution in Ruby. Return the maximum contiguous subsum in O(n) time and O(1) memory. I also, wrote some unit tests just in case ;)
def largest_contiguous_subsum(array)
max_sum = 0
current_sum = 0
array.each do |num|
current_sum += num
max_sum = current_sum if current_sum >= max_sum
current_sum = 0 if current_sum < 0
end
return max_sum
end
Upvotes: 0
Reputation: 2003
Here is the C++ Code I just implemented and tested on Visual Studio 2012.
int maxSum(int *A, int lo, int hi) {
int left = lo, right = lo, sum = INT_MIN, currentMaxSum = 0, maxLeft = lo, maxRight = lo;
for(int i = lo; i < hi; i++) {
currentMaxSum += A[i];
if(currentMaxSum > sum) {
sum = currentMaxSum;
right = i;
maxLeft = left;
maxRight = right;
}
if(currentMaxSum < 0) {
left = i+1;
right = left;
currentMaxSum = 0;
}
}
printf("Maximum sum contiguous subarray :");
for(int i = maxLeft; i <= maxRight; i++)
printf(" %d", A[i]);
printf("\n");
return sum;
}
Below is the main() code to call the above function.
int main() {
int A[] = {3,-4, -3, 2, 6};
int N = sizeof(A) / sizeof(int);
printf("Maximum sum : %d\n", maxSum(A, 0, N));
return 0;
}
Upvotes: 0
Reputation: 382
This is the correct Java Code which will handle scenarios including all negative numbers.
public static long[] leftToISumMaximize(int N, long[] D) {
long[] result = new long[N];
result[0] = D[0];
long currMax = D[0];
for (int i = 1; i < N; i++) {
currMax = Math.max(D[i], currMax + D[i]);
result[i] = Math.max(result[i - 1], currMax);
}
return result;
}
Upvotes: 0
Reputation: 1
static void MaxContiguousSum(int[] x, int lb, int[] result)
{
int start, end, sum, testSum;
start = lb;
end = lb;
/* Empty vector has 0 sum*/
sum = 0;
testSum = 0;
for (int i=lb; i < x.length; i++)
{
if (sum + x[i] < 0)
{
/* Net contribution by current term is negative. So, contiguous sum lies in [start,i-1]
or [i+1, array upper bound]*/
MaxContiguousSum(x, i+1, result);
if (result[0] < sum)
{
result[0] = sum;
result[1] = start;
result[2] = end;
}
return;
}
else
{
testSum += x[i];
if (testSum > 0)
{
/* Move the end marker since incrementing range is beneficial. */
end = i;
/* update the sum*/
sum += testSum;
/* reset the testSum */
testSum = 0;
}
}
}
/* Update the results */
result[0] = sum;
result[1] = start;
result[2] = end;
return;
}
Upvotes: 0
Reputation: 11
Alex, you have a very elegant algorithm but it needs correction for an array that contains a single element that is negative.
Of course, in the original algorithm of Kadane's, one can get the subarray start and end indexes which is useful for knowing the "path".
Here's an inelegant but I think correct Python function:
def max_subarray(A):
(maxSum, maxStartIndex, maxEndIndex) = (float("-inf"), 0, 0)
(currentMaxSum,currentStartIndex,currentEndIndex ) = (0,0,0)
for item in A:
currentMaxSum = currentMaxSum + item
if currentMaxSum > maxSum :
(maxSum, maxStartIndex, maxEndIndex) = (currentMaxSum, currentStartIndex, currentEndIndex)
if currentMaxSum < 0 :
currentMaxSum = 0
currentStartIndex = currentEndIndex + 1
# continue here.
currentEndIndex = currentEndIndex + 1
return (maxSum, maxStartIndex, maxEndIndex)
Upvotes: 1
Reputation: 882591
Well explained in the wikipedia entry about the subject. I find the Python code (i.e., executable pseudocode) they give for Kandane's Algorithm to be a little gem:
def max_subarray(A):
max_so_far = max_ending_here = 0
for x in A:
max_ending_here = max(0, max_ending_here + x)
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
Upvotes: 7
Reputation: 754900
This is discussed in Column 7 of the 1st Edition or Column 8 of the 2nd Edition of 'Programming Pearls' by Jon Bentley.
Upvotes: 2