问题描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例:输入的数组为1, -2, 3, 10, -4, 7, 2, -5,
和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
分析:
int maxSum(int* a, int n)
{
int sum = 0; //当前子数组和
int max = 0; //记录当前最大和的值
for (int i = 0; i<n; ++i)
{
if (sum<0) //当前子数组和小于0,为负数
sum = a[i];
else //当前和大于0
sum += a[i];
if (sum>max) //当前和大于之前记录的最大和,对max进行更新
max=sum;
}
return max;
}
我们的问题是要选出“和最大”的连续子数组:
- 要点一:和最大;
要点二:连续;
所以我们选择的标准是和,我们可以遍历数组,逐个相加,当此时相加的和小于0时,(就可以对前面的值进行抛弃),我们就可以对这个我们的子数组进行更新,从下一个数从新进行记录,每次用和sum和记录的之前记录的max进行比较,当此时的和sum>max,对max的记录值进行更新。直到遍历完这个数组,就可以得到数组的最大子数组和。
具体:
当sum的和为-1时,这是就可以对{1,-2}进行抛弃,因为无论后面与那些数进行组合,有这两个数必然会比没有这两个数和小
总结:设sum为包含第i个元素的连续子数组的和,max 当前记录的最大子数组的和。
对第i+1个元素有两种选择:
- 做为新子数组的第一个元素
- 放入前面找到的子数组