算法竞赛入门经典p8.1 最大连续子序列和的O(n3) O(n2) O(nlogn) O(n)

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的值即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值