最大连续子数组和(最大子段和)

最大连续子数组和(最大子段和)

一、问题描述

问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。

二、程序设计与实现

1、程序设计思想

  • 枚举法:确定每个字段和的开始位置(从1~n),然后计算该位置以后的每一个长度的字段和,随时更新最大字段和,但此法在数据量逐渐多时,运行的时间也随之暴涨,此法的时间复杂度为O(n^2)。
  • 分治法:通过分治的思想求最大子段和,将数组分平均分为两个部分,则最大子段和会存在于三种情况下:
    (1)、最大子段和出现在左端,可用递归求的;
    (2)、最大子段和出现在右端,可用递归求得;
    (3)、最大字段和出现在中间,则先计算出左端的最大字段和s1, 再计算出右端的最大字段和s2,则s1+s2为所求。
  • 动态规划:运用了动态规划的思想来解决最大子段和问题:
    通过遍历累加这个数组元素,定时的更新最大子段和,
    如果当前累加数为负数,直接舍弃,重置为0,然后接着遍历累加。
    时间复杂度:O(n),此法运行速度最快,所以用此法进行编译程序。

2、程序编译

package koko;
import java.util.*; 
public class mkmk {
	public static int maxSubSum1(int []a){
	       int maxSum=0; int nowSum=0;
	       for(int i=0;i<a.length;i++){
	           nowSum=nowSum+a[i];
	           if(nowSum>maxSum){//更新最大子段和
	               maxSum=nowSum;
	           }
	           if(nowSum<0){//当当前累加和为负数时舍弃,重置为0
	               nowSum=0;
	           }
	       }   
	       return maxSum;
	   }
	public static void main(String[] args){ 
		Scanner sb = new Scanner(System.in);  
		int n = sb.nextInt();//定义数组个数
		int i;
		int []a = new int[100];//定义数组最大数据个数
		for(i=0;i<n;i++)
			a[i]=sb.nextInt();
		int result=maxSubSum1(a);
		System.out.println("连续子元素的最大和为:"+result);
		sb.close();
	}
}

三、代码运行测试及测试用例选择

判定/条件覆盖

(1)nowSum>maxSum nowSum<0 测试用例:{-1,2,2,3,4,5}
(2)nowSum<=maxSum nowSum>=0测试用例:{-6,-2,13,-7,14,-1,-2,-2}
(3)nowSum>maxSum nowSum>=0测试用例:{1,2,3,4,1,2}
(4)nowSum<=maxSum nowSum<0测试用例:{-1,-2,-4,-7,-9}
测试代码为:

package koko;

import static org.junit.Assert.*;

import org.junit.Test;

public class mkmktest {

	@Test
	public void test1() {
		int []a={-1,2,2,3,4,5};
		assertEquals(16,mkmk.maxSubSum1(a));
	}
	@Test
	public void test2(){
		int []a={-6,-2,13,-7,14,-1,-2,-2};
		assertEquals(20,mkmk.maxSubSum1(a));
	}
	@Test
	public void test3(){
		int []a={1,2,3,4,1,2};
		assertEquals(13,mkmk.maxSubSum1(a));
	}
	@Test
	public void test4(){
		int []a={-1,-2,-4,-7,-9};
		assertEquals(0,mkmk.maxSubSum1(a));
	} 

}

测试结果如图所示:

经过测试,四个用例全部正确。

四、程序代码

posted @ 2018-04-01 16:11  CheungZeO  阅读(286)  评论(0编辑  收藏  举报