题目描述
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。
求所有子数组的和的最大值。
要求时间复杂度为O(n)。
例如:
输入数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出该子数组的和为18。
输入数组为{6,-2,-3,7,-15,1,2,2},和最大的子数组为{6,-2,-3,7},因此输出该子数组的和为8。
方法一:分析数组规律
//连续子数组的最大和:数组分析,累加和
public int MaxSumOfSubArray(int[] array){
if(array==null || array.length ==0) return 0;
int curSum = array[0];
int maxSum = array[0];
for(int i=1; i<array.length; i++){
if(curSum>=0)
curSum += array[i];
else
curSum = array[i];
if(curSum > maxSum)
maxSum = curSum;
}
return maxSum;
}
方法二:动态规划思想
状态方程:max( dp[ i ] ) = getMax( max( dp[ i -1 ] ) + arr[ i ] , arr[ i ] ),意义是:从头开始遍历数组,遍历到数组元素 arr[ i ] 时,连续的最大的和可能为 max( dp[ i -1 ] ) + arr[ i ] ,也可能为 arr[ i ] ,做比较即可得出哪个更大,取最大值。
时间复杂度为O(n)。
//连续子数组的最大和:动态规划
public int MaxSumOfSubArray1(int[] array){
if(array==null || array.length ==0) return 0;
int curSum = array[0];
int maxSum = array[0];
for(int i=1; i<array.length; i++){
if ( (curSum+array[i]) > array[i])
curSum = curSum+array[i];
else
curSum = array[i];
if(curSum>maxSum)
maxSum = curSum;
}
return maxSum;
}
执行结果
注意测试都是负数的情况