最大子序列和问题的求解(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);
	}

结果


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值