题目:输入一个整型数组,数组里有正数也有负数,数组中一个或者连续的多个整数组成一个子数组,求所有子数组的最大值,要求时间复杂度为O(n)
分析:暴力法,枚举所有子数组并求出它们的和,一个长度为n的数组,共有n(n+1)/2个子数组,计算出所有子数组的和,最快也需要O(n^2)时间。分析数组规律发现,若前几步累加的和已经小于0了,则舍弃,累加和从当前数字算起,每次累加和若增大,则更新。动态规划,若用f(i)表示以第i个数字结尾的子数组的最大和,则推到公式如下:
f(i)=array[i], f(i-1)<=0||i=0
f(i)=f(i-1)+array[i],f(i-1)>0&&i!=0
public class wr31arrayMaxSum {
public static int FindGreatestSumOfSubArray(int[] array){
if(array==null || array.length==0){
return 0;
}
int curSum=array[0];//当前和的最大值
int greatesSum=array[0];
for(int i=1;i<array.length;i++){
// 如果当前和最大值小于零了,之前的累计和被抛弃,从现在起开始累计
if(curSum<=0){
curSum=array[i];
}
// 当前和大于零,加上当前值
else{
curSum+=array[i];
}
if(curSum>greatesSum){//存储最大值
greatesSum=curSum;
}
}
return greatesSum;
}
// 动态规划
public static int find(int []array){
int f=array[0];
int max=array[0];
for(int i=1;i<array.length;i++){
max=(max<0)?array[i]:max+array[i];
f=(max>f)?max:f;
}
return f;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] array={-2,-8,-1,-5,-9};
// int [] array={1,-2,3,10,-4,7,2,-5};
System.out.println(FindGreatestSumOfSubArray(array));
System.out.println(find(array));
}
}