算法一:
<div>{CSDN:CODE:maxsubsum1.java}</div>
三次循环 O(N³)
算法二:
public static int maxSubSum(int []a){
int maxSum = 0;
for(int i=0;i<a.length;){
int thisSum = 0;
for(int j=i;j<a.length;j++){
thisSum+=a[j];
if(thisSum>maxSum){
maxSum = thisSum;
}
}
}
return maxSum;
}
每次计算i到j的和
两次循环 O(N²)
算法三:
public static int maxSubSum(int []a){
int maxSum = 0,thisSum=0;
for(int i;i<a.length;i++){
thisSum+=a[i];
if(thisSum>maxSum){
maxSum = thisSum;
}else if(thisSum<0){
thisSum = 0;
}
}
return maxSum;
}
一次循环 O(N)
算法四:分治
public static int maxSubSum(int []a){
return execute(a,0,a.length);
}
public int execute(int []a,int left,int right){
if(left==right){ //Base Case
if(a[left]>0)
return a[left];
else return 0;
}
int center = (left+right)/2;
int leftMaxSum = execute(int []a,int left,int center);
int rightMaxSum = execute(int []a,int center+1,right);
int maxLeftBorderSum = 0,thisLeftBorderSum = 0;
for(int i=center;i>=0;i--){
thisLeftBorderSum+=a[i];
if(thisLeftBorderSum>maxLeftBorderSum)
maxLeftBorderSum = thisLeftBorderSum;
}
int maxRightBorderSum = 0,thisRightBorderSum = 0;
for(int i=center+1;i<=a.length;i++){
thisRightBorderSum+=a[i];
if(thisRightBorderSum>maxRightBorderSum)
maxRightBorderSum = thisRightBorderSum;
}
return max3(leftMaxSum ,rightMaxSum ,maxLeftBorderSum+maxRightBorderSum);
}
最大子序列应该在左边,右边,过中点的两边各有。这三种情况之中。
每次求左边(右边)的最大子序列,又可以将其看作新的母序列。所以可用递归。