最大子序列和问题的求解(Java实现)

对于最大子序列和问题的求解方法,目前我掌握了四个算法。一开始学习的时候,这四个算法中让我有点头疼的是其中的递归算法(我是真的不喜欢用递归的啊<哭唧唧),搞来搞去,最终还是弄懂是怎么一回事了。

在这篇文章中,我会写出四个算法并加以解释。

【算法1】这个算法以及算法2都很容易理解,他们就是把每个数以及每个数与后边相邻的数的和做比较,谁大就用谁的。

//该算法运行时间为O(n^3)  
    public static int maxSum1(int [] a){
    	int maxSum=0;
    	for(int i=0;imaxSum){
    				maxSum=thisSum;
    			}
    		}
    	return maxSum;
    }
    

【算法2】比算法1少了一个for循环

//该算法运行时间为O(n^2)
    public static int maxSum2(int [] a){
    	int maxSum=0;
    	for(int i=0;imaxSum){
    				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;imaxSum){
    			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);
	}

结果

最大子序列和问题的求解(Java实现)_第1张图片

你可能感兴趣的:(Java数据结构笔记)