最大子序列和的四种解法

在这里插入图片描述
枚举法

#include<iostream>

#define N 10

using namespace std ;

int main()

{

int A[N] = {1,3,-5,2,6,-7,8,1,0,-1};

int best = A[0];

for(int i = 0 ; i < N ; i++){

for(int j = i; j < N ; j++){

int sum = 0 ;

for(int k = i ; k <= j ;k++){

sum+=A[k];

}

if(sum > best ) best = sum;

}

}

cout<<best;

return 0 ;

}

这种方法是依次计算出所有的和进行比较

第一次取第一个数

第二次取第一个和第二个数

直到第一个到第n个,然后从第二个开始

走遍了所有情况

时间复杂度为O(n³)

2进行分析后对枚举法进行改进

#include<iostream>

#define N 10

using namespace std ;

int main()

{

int  best = 0 ;

int A[10] = {1,3,-5,2,6,-7,8,1,0,-1};

int s[11];

s[0] = 0 ;

for(int i = 1 ; i <= N ; i++){

s[i] = s[i-1]+A[i];

}

for(int i = 0 ; i < N ; i++){

for(int j = i ; j < N ; j++){

best = best>s[j]-s[i-1] best:s[j]-s[i-1];

}

}

cout<<best;

return 0 ;

}

先计算出从第一个数到第n个数的和

然后用从第一个数到第n个数的和 减去第一个数到第m个数的和可求得m到n的和

进行比较后也可得出正确结果

时间复杂度为O(n²)

3分治法

#include<iostream>

#define N 10

using namespace std;

int maxsum(int *A , int x , int y );

int main()

{

int best = 0 ;

int A[N] = {1,3,-5,2,6,-7,8,1,0,-1};

best = maxsum(A,0,N);

cout<<best;

return 0 ;

}

maxsum(int *A , int x , int y ){

if( y – x == 1 ) return A[x]>0 A[x]:0;

int m = x+ (y-x)/2;

int maxsum1 = maxsum(A,x,m);

int maxsum2 = maxsum(A,m,y);

int maxsum3 = 0 ;

int sum = 0 ;

for(int i = m-1 ; i >= 0 ;i–){

sum+=A[i];

if(sum > maxsum3 ) maxsum3  = sum;

}

int maxsum4 = 0 ;

sum = 0 ;

for(int i = m ; i < y ;i++){

sum+=A[i];

if(sum > maxsum4 ) maxsum4  = sum;

}

maxsum3+=maxsum4;

int max = 0 ;

if(maxsum1>max) max = maxsum1;

if(maxsum2>max) max = maxsum2;

if(maxsum3>max) max = maxsum3;

return max ;

}

再次分析后发现 将数组分为左右两边

和最大子序列在左边 右边 或者中间跨左右

于是可分而治之 从中间分开 递归到只剩两个数时 返回他们的和最大子序列

即左边,右边,或者二者相加到最后将三个数进行比较可得到和最大子序列

此时时间复杂度为O(n*logn)

4 在线处理

#include<iostream>

#define N 10

using namespace std ;

int main()

{

int A[N] = {1,3,-5,2,6,-7,8,1,0,-1};

int ThisSum , MaxSum;

int i ;

ThisSum = MaxSum = 0 ;

for(i = 0 ; i < N ;i++ ){

ThisSum += A[i];

if(ThisSum > MaxSum) MaxSum = ThisSum;

else if(ThisSum < 0 ) ThisSum = 0 ;

}

cout<<MaxSum;

return 0 ;

}

从左到右进行寻找

设置当前和为0 最大和为0

加上下一个数时会出现三种情况

大于最大和 那么将最大和的值赋为当前和
小于最大和但当前和大于0 那么就有可能在加上下一个数时大于最大和 所以将当前和赋值为加上后的值 但最大和不变
小于最大和并且当前和小于0 最大和依旧不变,但是将当前最大和赋值为0,因为负数无论加什么数都会让那个数变小
此时时间复杂度变成了O(n)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值