最大子序列和問題的求解(Java實現)

對於最大子序列和問題的求解方法,目前我掌握了四個算法。一開始學習的時候,這四個算法中讓我有點頭疼的是其中的遞歸算法(我是真的不喜歡用遞歸的啊<哭唧唧),搞來搞去,最終還是弄懂是怎麼一回事了。

在這篇文章中,我會寫出四個算法並加以解釋。

【算法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);
	}

結果


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章