T(n) = O(n3)
best = A[1];
for(int i = 1;i <= n;i++)
for(intj = i;j <= n;j++) {
intsum = 0;
for(intk = i;k <= j;k++)
sum+= A[k];
if(sum> best)
best= sum;
}
T(n) = O(n2)
对数组作预处理
S[0] = 0;
for(int i = 1;i <= n;i++)
S[i]= S[i -1] + A[i];
for(int i = 1;i <= n;i++)
for(intj = i;j <= n;j++)
best= max(best,S[j] - S[i - 1]);
-
T(n) = O(nlogn)
int maxsum(int* A,int x,int y) {
intv,L,R,maxs;
if(y- x == 1) return A[x];
intm = x + (y - x) / 2;
intmaxs = max(maxsum(A,x,m),maxsum(A,m,y));
v= 0;L = A[m - 1];
for(inti = m - 1;i >= x;i--) L = max(L,v += A[i]);
v= 0;L = A[m];
for(inti = m;i < y;i++) R = max(R,v += A[i]);
returnmax(maxs,L + R);
}
Maxs:完全位于某一边的连续最大和
L+R:起点位于左半,终点位于右半的最大连续和
处理数组分割:左开右闭
1.[x,y)被分成[x,m)和[m,y),不需要在任何地方加减1
2.空区间的表示:[x,x) 而不是[x,x-1)
分成元素尽可能相等的两半:注意到
5/2 = 2
-5/2 = -2
计算机"/"的取整方向是朝零取整,而不是向下取整
X和y的平均数我们用:x+(y-x)/2,而不是(x+y)/2,确保分界点总是靠近区间起点,(此题中非必要)
x+(y-x)/2举例:
1. y>x (x为起点)
[1,9)中点为5,计算结果为5,靠近起点
[1,8)中点为4和5,计算结果为4,靠近起点
2. y<x(x为起点)
[-5,-1)中点为-3,计算结果为-3,靠近起点
[-6,-1)中点为-4和-3,计算结果为-3,靠近起点
[-6,-1)中点为-4和-3,计算结果为-3,靠近起点(-6为起点)
而(x+y)/2对于[-6,-1) -6为起点:计算结果却是-3,没有靠近起点
T(n) = O(n)
思路:
m初始化为0,从左到右逐个累加到变量m中,若累加过程中m为负数,则置0,继续向右累加,
max用数组最左边第一个数初始化,m每次加完一个位置后,将m的值与变量max的值相比,其中取较大的存入max,这样,只需从左到右遍历一遍,输出max的值即可。