我是靠谱客的博主 拼搏钢笔,最近开发中收集的这篇文章主要介绍最大子序列和问题求解联机算法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题: 给定(可能有负数)的整数 A 1 , A 2 , … , A n A_{1},A_{2},ldots ,A_{n} A1,A2,,An 的最大值。
解决此问题有四个算法:
算法一:

public static int maxSubSuml ( 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 ;
}

运行时间为 O ( N 3 ) Oleft( N^{3}right) O(N3) ,这取决于第9、10行,按照(粗略的计算)最坏的要求计算运行了3赐循环。
按照精确的计算为: ∑ i = 0 N − 1 ∑ j = i N − 1 ∑ k = i j 1 sum ^{N-1}_{i=0}sum ^{N-1}_{j=i}sum ^{j}_{k=i}1 i=0N1j=iN1k=ij1 得到 N 3 + 3 N 2 + 2 N 6 dfrac {N^{3}+3N^{2}+2N}{6} 6N3+3N2+2N。可以看出在第三层for循环中过分的耗费了时间。
算法二:

public static int maxSubSum2( 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 ;
}

运算时间为(大概): O ( N 2 ) Oleft( N^{2}right) O(N2)
算法三:
“分治”策略:将问题分成两个大致相等的子问题,然后递归的对它们求解;然后再将两个子问题的解修补到一起并按照要求做一些附加工作,最后得到整个问题的解。

public static int maxSumRec ( 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 maxLeftSun = maxSumRec ( a, left, center ) ;
	int maxRightSum = maxSumRec ( a, center + 1 , right );
	
	int maxLeftBorderSum = 0 ;
	int leftBorderSum = 0 ;
	
	for (int i=center;i>=left;i--){
		leftBorderSum+=a[i];
		if(leftBorderSum>maxLefBorderSum){
			maxLeftBorderSum=leftBorderSum;
		}
	}
	
	int maxRightBorderSum=0;
	int rightBorderSum=0;
	for(int i=center+1;i<=right;i++){
		rightBorderSum+=a[i];
		if(rightBorderSum>maxRightBorderSum){
			maxRightBorderSum=rightBorderSum;
		}
	}
	
	//max(a,b,c);是求a,b,c,三者中的最大值
	return max(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
	
}

运算时间为 O ( N log ⁡ N ) Oleft( Nlog Nright) O(NlogN) ,这个算法分析N是偶数。
算法四:

public static int maxSubSum(int [ ] a ){
	int maxSum=0;
	int thisSum=0;
	
	for(int j=0; j<a.length; j++){
		thisSum+=a[j];
		if(thisSum>maxSum){
			maxSum=thisSum;
		}
		else if(thisSum<0){
			thisSum=0;
		}
		
		return maxSum;
	}
}

运行时间为: O ( N ) Oleft( Nright) O(N)

分析

算法1和算法2中,j代表当前序列的终点,而i代表当前序列的起点。而如果我们不需要知道最佳子序列的具体位置的话,i的使用则可以被优化(算法四)。
算法四:假设a[i]是负的,那么它不是最有序列的起点,因为都可以通过a[i+1]作为起点来改进。同样,任何负的子序列都不是最优序列的前缀。i不仅可以推到i+1,还可以推到j+1;因此我们的最优解一个也不会错过。

联机算法

在任意时刻算法对要操作的数据只读入(扫描)一次,一旦被读入并处理,它就不需要在被记忆了,而在此处理过程中算法能对它已经读入的数据立即给出相应子序列问题的正确答案。
优点: 占用空间少,所用时间少。
缺点: 不宜设计,正确性不易观察,同时附加保留信息较少。

最后

以上就是拼搏钢笔为你收集整理的最大子序列和问题求解联机算法的全部内容,希望文章能够帮你解决最大子序列和问题求解联机算法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部