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