一、题目描述
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
示例1
输入
[1,-2,3,10,-4,7,2,-5]
返回值
18
二、思路
一开始我运用动归的典型思想,先从上考虑问题,从最后一个数开始划分,设f(n)为n个数的最大子数组的和,划分子问题时,想当然的认为,如果a[i]>0,则f(n)=f(n-1)+a[i],这样写显然是错的,分析一下,可以得知,如果按照这样来划分子问题,最后得出的结果,是所有正数的和,显然是错的,因为题目要求连续子数组的和,而f(n-1)不一定是以a[n-1]为末尾的子序列的和。
于是我换了一种方法划分子数组,设f(n)是以a[n]为末尾的连续子数组的和,到了这里,我还简单地认为动态规划划分子问题,就是简单的从最后一个数开始往下划分,这种思想显然是错误的,因为设f(n)是以a[n]为末尾的子数组的和,但是显然,以a[n]为末尾的子数组的和不一定是整个数组连续子数组的最大和。
因此,正确的方法,应该是,把以数组中每一个元素结尾的子序列的最大和都求一下,找出一个最大值。这个最大值才是整个数组的最大值。
设f(i)为以a[i]为结尾的子数组的最大和,划分子问题,如果f(i-1)+a[i]>a[i],
则,f(i)=f(i-1)+a[i],否则,f(i)还是为f(i-1)。
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int n=array.size();
int max=array[0];
vector<int> maxvalue(n+1,0);
maxvalue[0]=array[0];
for(int i=1;i<n;i++){
if(maxvalue[i-1]+array[i]>array[i])
maxvalue[i]=maxvalue[i-1]+array[i];
else
maxvalue[i]=array[i];
if(maxvalue[i]>max)
max=maxvalue[i];
}
return max;
}
};