问题描述:
给定一个整数序列,a0, a1, a2, …… , an(项可以为负数),求其中最大的子序列和。如果所有整数都是负数,那么最大子序列和为0;
例如:对于序列-2, 11, -4, 13, -5, –2。 所求的最大子序列和为20(从11到13,即从a1到a3)。
package com.ql;
import java.util.Arrays;
/**
* @author Administrator
*
*/
public class MaxSubSum {
public static void main(String[] args){
int [] a={-2,11,-4,13,-5,-2};
//System.out .println(maxSubSum1(a));
//System.out .println(maxSubSum2(a));
//System.out .println(maxSubSum3(a));
System.out .println(maxSubSum4(a));
}
/**
* @author Administrator
* 运行时间为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;
}
/**
* @author Administrator
* 运行时间为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;
}
/**
* @author Administrator
* 运行时间为O(NlogN)
*/
private 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 maxLeftSum, int maxRightSum, int i) {
int[] str = {maxLeftSum,maxRightSum,i};
Arrays.sort(str);
return str[2];
}
public static int maxSubSum3(int [] a){
return maxSumRec(a, 0, a.length-1);
}
/**
* @author Administrator
* 运行时间为O(N)
*/
public static int maxSubSum4(int [] a){
int maxSum = 0,thisSum = 0;
for(int j = 0;j < a.length;j++){
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
else if(thisSum < 0)
thisSum = 0;
}
return maxSum;
}
}