题目:
输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
思想:如果数组中所有的数都是负数,返回最大的负数便是所求。
若有正数也有负数,那么定义一个变量sum表示所求的最大子数组和值,定义一个变量tmp保存当前计算的子数组的和值。
我觉得此算法的最关键之处便是:一个数组例如aABc(其中小写代表一个数字,大写代表一个子数组),如果B的和最大且A的和大于零,
则B的和不可能是最大的,最大的应该是子数组AB。算法中对数组进行一次遍历,用tmp记录当前子数组的和,只要tmp〉0,
拥有最大和的子数组的开头肯定是tmp的开头;当tmp<0时,tmp重新从当前数组元素开始计算。每遍历一个数组元素,
便比较tmp与sum的大小,从而改变sum的值。
我觉得也正是因为上面分析的关键之处,此算法才能有个O(n)的时间复杂度。
本人语言表达能有极为有限,所有要是有什么看起来很难懂得地方,
希望指出来,以便我提高自己的语言表达能力,若能如此,我将不胜感激。
#include<iostream>
using namespace std;
int maxSum(int* a,int length){
int tmp = 0,sum = 0;
tmp = a[0];
for(int i = 1;i < length;i++){
if(tmp < a[i])
tmp = a[i];
}
if(tmp < 0)
return tmp;
tmp = 0;
for(int i = 0; i < length; i++){
if(tmp <= 0)
tmp = a[i];
else
tmp += a[i];
if(sum < tmp)
sum = tmp;
}
return sum;
}
int main()
{
int a[] = {1,-8,6,3,-1,5,7,-2,0,1};
int length = 10;
cout<<maxSum(a,length)<<endl;
system("pause");
return 0;
}