對於最大子序列和問題的求解方法,目前我掌握了四個算法。一開始學習的時候,這四個算法中讓我有點頭疼的是其中的遞歸算法(我是真的不喜歡用遞歸的啊<哭唧唧),搞來搞去,最終還是弄懂是怎麼一回事了。
在這篇文章中,我會寫出四個算法並加以解釋。
【算法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);
}
結果