题目:
输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
要求时间复杂度为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; }