求最大子序列和(Java实现)

【问题描述】最大子序列和问题:给定整数A1, A2, ..., An(可能有负数),ΣAk的最大值(为方便起见,如果所有整数均为负数,则最大子序列和为0)。

通过四种方式来完成算法的实现,时间复杂度分别为:O(N*N*N)、O(N*N)、O(N*log N)、O(N)

【源码1】

package cn.edu.nwsuaf.cie.qhs.maxsubsum;

/**
 * 求最大子序列和(1)
 * @author 静寞小森(沧海森林)
 * 下面的这种做法来求和,应该是程序员最直观想到的,时间复杂度为:O(N*N*N)
 *
 */

public class MaxSubSum1 {

	public static int maxSum(int[] array){
		int maxSum = 0;
		for(int i = 0 ; i < array.length ; i++){
			for(int j = i ; j < array.length;j++){
				 int curSum = 0;
				for (int k = i; k <= j; k++){
					curSum += array[k];
					if(curSum > maxSum){
						maxSum = curSum;
					}
				}
			}
		}
		return maxSum;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = new int[]{4,-3,5,-2,-1,2,6,-2};
		long startTime = System.nanoTime();
		System.out.println("最大子序列和为:"+MaxSubSum1.maxSum(array));
		long endTime = System.nanoTime();
		System.out.println("程序耗时为:"+(endTime-startTime)+" ns");
	}
}
【源码2】

package cn.edu.nwsuaf.cie.qhs.maxsubsum;

/**
 * 求最大子序列和(2)
 * 
 * @author 静寞小森(沧海森林)
 *         第二种做法,是对做法(1)进行一下分析,可以得知,程序中第三层循环不是必须的,因为这个过程可以包含在第二层循环中,所以可以考虑去掉。
 *         去掉一个for循环,可以得到循环的次数减少了n的倍数,所以时间复杂度为O(N*N)
 * 
 */
public class MaxSubSum2 {
	public static int maxSum(int[] array) {
		int maxSum = 0;
		for (int i = 0; i < array.length; i++) {
			int curSum = 0;//这个变量的声明和初始化要提到第二层for的外面
			for (int j = i; j < array.length; j++) {
				//在这里,就已经包括了(1)中的k的那个循环
				curSum += array[j];
				if (curSum > maxSum) {
					maxSum = curSum;
				}
			}
		}
		return maxSum;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = new int[]{4,-3,5,-2,-1,2,6,-2};
		long startTime = System.nanoTime();
		System.out.println("最大子序列和为:"+MaxSubSum2.maxSum(array));
		long endTime = System.nanoTime();
		System.out.println("程序耗时为:"+(endTime-startTime)+" ns");
	}
}

【源码3】

package cn.edu.nwsuaf.cie.qhs.maxsubsum;

/**
 * 求最大子序列和(3)
 * 
 * @author 静寞小森(沧海森林)
 *         第三种方法,我们将采用“分而治之”的想法,进行编码。因为本程序,最大子序列和只能出现在三个位置上:
 *         左半部分、右半部分、跨着左右两半部分;所以我们可以采用二分的“分而治之”来进行分开解决问题。可知其时间复杂度为:O(N*log N)
 */

public class MaxSubSum3 {
	
	private static int max3(int a,int b,int c){
		int temp = Math.max(a, b);
		return Math.max(temp, c);
	}
	
	private static int maxSumRec(int[] array,int left,int right){
		if (left == right)
			return array[left] > 0 ? array[left] : 0;
		//二分
		int center = (left+right)>>1;//右移位一次,为除法的除以2,但是效率比较高
		int maxLeftSum = maxSumRec(array,left,center);
		int maxRightSum = maxSumRec(array,center+1,right);

		int maxLeftBorderSum = 0, curLeftBorderSum = 0;
		for(int i = center;i >= left; i--){
			curLeftBorderSum += array[i] ;
			if(curLeftBorderSum > maxLeftBorderSum)
				maxLeftBorderSum = curLeftBorderSum;
		}
		int maxRightBorderSum = 0, curRightBorderSum = 0;
		for(int i = center+1; i <= right;i++){
			curRightBorderSum += array[i];
			if(curRightBorderSum > maxRightBorderSum)
				maxRightBorderSum = curRightBorderSum;
		}
		
		return max3(maxLeftSum,maxRightSum,maxRightBorderSum+maxLeftBorderSum);
	}
	
	public static int maxSum(int[] array){
		return maxSumRec(array,0,array.length-1);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = new int[]{4,-3,5,-2,-1,2,6,-2};
		long startTime = System.nanoTime();
		System.out.println("最大子序列和为:"+MaxSubSum3.maxSum(array));
		long endTime = System.nanoTime();
		System.out.println("程序耗时为:"+(endTime-startTime)+" ns");
	}
	
}
【源码4】

package cn.edu.nwsuaf.cie.qhs.maxsubsum;

/**
 * 求最大子序列和(4)
 * 
 * @author 静寞小森(沧海森林)
 *        第四种方法,是通过一个“联机算法”进行的最优算法计算,时间复杂度仅为O(N)
 * 
 */

public class MaxSubSum4 {

	public static int maxSum(int[] array){
		int maxSum = 0, curSum = 0;
		for (int i = 0; i < array.length; i++){
			curSum += array[i];
			
			if(curSum > maxSum){
				maxSum = curSum;
			}else if(curSum < 0){
				curSum = 0;
			}
		}
		return maxSum;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = new int[]{4,-3,5,-2,-1,2,6,-2};
		long startTime = System.nanoTime();
		System.out.println("最大子序列和为:"+MaxSubSum3.maxSum(array));
		long endTime = System.nanoTime();
		System.out.println("程序耗时为:"+(endTime-startTime)+" ns");
	}
}



你可能感兴趣的:(java,c,算法,String,Class)