Maximum Subsequence Sum Problem
The first algorithm O(N^3)
public static int maxSubSum1(int a[]){
int maxSum=0;
for(int i=0;i<a.length;i++){
for(int j=i;j<a.length;j++){
int thisSum=0;
for( int k=i;k<j;k++){
thisSum+= a[k];
}
if(thisSum>maxSum)
maxSum=thisSum;
}
}
return maxSum;
}
The second algorithm O(N^2)
public static int maxSubSum2(int a[]){
int maxSum=0;
for(int i=0;i<a.length;i++){
int thisSum=0;
for(int j=i;j<a.length;j++){
thisSum +=a[j];
if(thisSum>maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
The third algorithm O(N logN), divide and conquer
The sum of the largest subsequences may occur in three places, either in the left half of the input data, or in the right half of the input data, or in the middle of the input data. The first two cases can be solved recursively. The maximum sum of the third case can be obtained by finding the maximum sum of the first half (including the last element of the first half) and the second half (including the first element of the second half). Add these two together at this point.
public static int maxSumRec(int a[] ,int left,int right){
if(left== right){
if(a[left]>0)
return a[left];
else
return 0;
}
int center = (left+right)/2;
int maxLeftSum = maxSumRec(a,left,center);
int maxRightSum = maxSumRec(a,center+1,right);
int maxLeftBorderSum = 0,leftBorderSum = 0;
for(int i=center;i>=left;i--){
leftBorderSum+= a[i];
if(leftBorderSum > maxLeftBorderSum){
maxLeftBorderSum = leftBorderSum;
}
}
int maxRightBorderSum = 0,rightBorderSum = 0;
for(int i=center+1;i<=right;i++){
rightBorderSum+= a[i];
if(rightBorderSum > maxRightBorderSum){
maxRightBorderSum = rightBorderSum;
}
}
return max3(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
}
private static int max3(int a, int b, int c) {
int ab = Math.max(a, b);
return Math.max(c, ab);
}
public static int maxSubSum3(int a[]){
return maxSumRec(a, 0, a.length-1);
}
The fourth algorithm O(N)
It is difficult to see the correctness of this algorithm. It can be seen that when a[i] is negative, it can not be used as the starting point of the most sequence, because any sequence containing a[i] as the starting point can be improved by using a[i+1] as the starting point. Similarly, any negative subsequence cannot be the prefix of the optimal subsequence. If the sub-sequence from a[i] to a[j] is detected to be negative in the loop, then I can be pushed forward. The key conclusion is that we can not only push I to i+1, but actually push it all the way to j+1. To see this clearly, let p be any subscript between i+1 and J. Any subsequence starting with subscript p is not larger than the corresponding subsequence starting with subscript i and containing the subsequence from a[i] to a[p-1], because the subsequent subsequence is not negative (j is the first subscript of the sequence that makes its value negative from subscript i). Therefore, there is no risk in pushing I to j+1.
public static int maxSubSum4(int a[]){
int maxSum=0,thisSum=0;
for(int i=0;i<a.length;i++){
thisSum+=a[i];
if(thisSum>maxSum)
maxSum = thisSum;
else if(thisSum<0)
thisSum = 0;
}
return maxSum;
}