对于最大子序列和问题的求解方法,目前我掌握了四个算法。一开始学习的时候,这四个算法中让我有点头疼的是其中的递归算法(我是真的不喜欢用递归的啊<哭唧唧),搞来搞去,最终还是弄懂是怎么一回事了。
在这篇文章中,我会写出四个算法并加以解释。
【算法1】这个算法以及算法2都很容易理解,他们就是把每个数以及每个数与后边相邻的数的和做比较,谁大就用谁的。
//该算法运行时间为O(n^3)
public static int maxSum1(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;
}
【算法2】比算法1少了一个for循环
//该算法运行时间为O(n^2)
public static int maxSum2(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;
}
【算法3】递归求解,用了“分治”策略。
//该算法时间复杂度为O(NlogN)
public static int max3(int a,int b,int c){
int maxnumber=Math.max(a, b);
return Math.max(c, maxnumber);
}
public static int maxSum3(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 maxSumLeft=maxSum3(a,left,center);//求出左半部分的最大子序列和
int maxSumRight=maxSum3(a,center+1,right);//求出右半部分最大子序列的和
int maxBorderLeft=0;int leftBorder=0;//包含左半部分最后一个数的最大值求解
for(int i=center;i>=left;i--){
leftBorder+=a[i];
if(leftBorder>maxBorderLeft){
maxBorderLeft=leftBorder;
}
}
int maxBorderRight=0;int rightBorder=0;//包含右半部分第一个数的最大值求解
for(int i=center+1;i<=right;i++){
rightBorder+=a[i];
if(rightBorder>maxBorderRight){
maxBorderRight=rightBorder;
}
}
return max3(maxSumLeft,maxSumRight,maxBorderLeft+maxBorderRight);
}
【算法4】联机算法。为什么这个算法是正确的呢,关键之处在于这个算法代码中的else语句,当前边有正数,且他是最大的子序列和,那他加上后边的大于零的数不也就是最大的吗!
//联机算法 该算法时间复杂度为O(n)
public static int maxSum4(int [] a){
int maxSum=0;int 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;
}
最后贴上我测试这几个算法的结果以及main函数
【main函数】
static int [] a={1,2,5,-6,-8,20};
public static void main(String args[]){
int firstsum=maxSum1(a);
int secondsum=maxSum2(a);
int thirdsum=maxSum3(a,0,a.length-1);
int forthsum=maxSum4(a);
System.out.print(firstsum+"\n"+secondsum+"\n"+thirdsum+"\n"+forthsum);
}
结果