Maximum Subarray Sum
Problem statement:
Given an array of both positive and negative integers, find the sum of contiguous subarray
of numbers which has largest sum
Ex:
{-2, -5, 6, -2, -3, 1, 5, -6}, then the maximum subarray sum is 7
Naïve Method:
• Using two loops.
• For every element in outer loop, the inner loop finds the max. sum possible
Compare the max. sum w.r.t. each element of outer loop with overall maximum
• Return overall maximum
Complexity: O(n2)
D.S. Adane, School of CSE, RBU, Nagpur 2
Kadane’s Method
Traverse over the array from left to right and for each element, find the maximum
sum among all subarrays ending at that element
The result will be the maximum of all these values
Central Idea:
To calculate the maximum sum of subarray ending at current element, say
Max_End, we can use the maximum sum ending at the previous element. So for
any element, we have two choices:
1. Extend the maximum sum subarray ending at the previous element by adding
the current element to it. If the maximum subarray sum ending at the previous
index is positive, then it is always better to extend the subarray.
2. Start a new subarray starting from the current element. If the maximum
subarray sum ending at the previous index is negative, it is always better to
start a new subarray from the current element.
D.S. Adane, School of CSE, RBU, Nagpur 3
Thus,
Max_End at index i = max(Max_End at index (i-1) + arr[i], arr[i])
Maximum of Max_End at any index is the answer
Algo:
int max_Subarray_Sum(int arr[], int size) {
int Max = arr[0]; // Overall Maximum
int Max_End = arr[0]; // Used for updation of list giving Maximum
for (int i = 1; i < size; i++) {
// Extend the maximum sum subarray ending at index i - 1 or
// starting a new subarray from index i
Max_End = (Max_End + arr[i] > arr[i]) ? Max_End + arr[i] : arr[i]);
// Update Max if maximum subarray sum ending at index i > Max
Max = (Max > Max_End) ? Max : Max_End;
}
return Max;
}
Complexity: O(n)
D.S. Adane, School of CSE, RBU, Nagpur 4
• Ex:
0 1 2 3 4 5 6 7
• arr[] = {-2, -5, 6, -2, -3, 1, 5, -6}
• Max = -2, Max_End = -2;
• i=1 to 7
• i=1 => arr[1] + Max_End = -7=> Max_End = -5, Max = -2
• i=2 => arr[2] + Max_End = 1 => Max_End = 6, Max = 6
• i=3 => arr[3] + Max_End = 4 => Max_End = 4, Max = 6
• i=4 => arr[4] + Max_End = 1 => Max_End = 1, Max = 6
• i=5 => arr[5] + Max_End = 2 => Max_End = 2, Max = 6
• i=6 => arr[6] + Max_End = 7 => Max_End = 7, Max = 7
• i=7 => arr[7] + Max_End = 1 => Max_End = 1, Max = 7
Return Max (7)
D.S. Adane, School of CSE, RBU, Nagpur 5
Divide and Conquer
• Can we apply Divide and Conquer to the problem to obtain better
complexity??
• Let us see….
• Steps:
• Divide the given array in two halves
• Return the maximum of following three
• Maximum subarray sum in left half (Make a recursive call)
• Maximum subarray sum in right half (Make a recursive call)
• Maximum subarray sum such that the subarray crosses the midpoint
D.S. Adane, School of CSE, RBU, Nagpur 6
• Algorithm:
int maxSubArraySum(int arr[], int l, int h) {
// Invalid Range: low is greater than high
if (l > h)
return INT_MIN;
// Base Case: Only one element
if (l == h)
return arr[l];
int m = (l + h) / 2;
return max(maxSubArraySum(arr, l, m ),
maxSubArraySum(arr, m + 1, h),
maxCrossingSum(arr, l, h));
}
D.S. Adane, School of CSE, RBU, Nagpur 7
int maxCrossingSum(int arr[], int l, int m, int h) { // Include elements on left of mid.
int sum = 0;
int l_sum = INT_MIN;
for (int i = m; i >= l; i--) {
sum = sum + arr[i];
if (sum > l_sum)
l_sum = sum;
}
// Include elements on right of mid
sum = 0;
int r_sum = INT_MIN;
for (int i = m+1; i <= h; i++) {
sum = sum + arr[i];
if (sum > r_sum)
r_sum = sum;
}
return max(l_sum + r_sum , left_sum, right_sum);
}
D.S. Adane, School of CSE, RBU, Nagpur 8
• Ex:
Arr[]= 0 1 2 3 4 5 6 7
-2, -5, 6, -2, -3, 1, 5, -6 mid=(0+7)/2=4
(mid)
-2, -5, 6, -2 1, 5, -6
(List 1) (List 2)
mid=(0+3)/2=2 mid=(5+7)/2=6
-2, -5 -2 1 -6
(List 3) (List 4) (List 5) (List 6)
mid=(0+1)/2=1
-2
(List 7)
D.S. Adane, School of CSE, RBU, Nagpur 9
steps 0 1 2 3 4 5 6 7
1 -2, -5, 6, -2, -3, 1, 5, -6
2 -2, -5, 6, -2 1, 5, -6
mSAS returns -6
3 -2, -5 -2 1 -6
mSAS returns -2 -2 mSAS returns -2 mSAS returns 1
From steps 3 to 1, MaxCrossingSum() returns Max value
Step 3: -2 -5 lsum = -7; rsum = -5; csum = -7-5-(-5) = -7; Max= -5; MaxCrossingSum returns -5
Step 2: List 1: -5 6 -2 List 2: 1 5 -6
lsum = 1; rsum = 4; csum = 1+4-6 = -1 lsum = 6; rsum = -1; csum = 6-1-5 = 0
MaxCrossingSum returns 4 MaxCrossingSum returns 6
Step 1: List: 4 -3 6
lsum = 1; rsum = 3; csum = 1+3-(-3) = 7
MaxCrossingSum returns 7
D.S. Adane, School of CSE, RBU, Nagpur 10
• Complexity??
• Every instance calls mSAS() twice for left and right sublists and mCS is
called once
• T(n) = 2T(n/2) + n
= O(n log n)
D.S. Adane, School of CSE, RBU, Nagpur 11