数据结构与算法分析--最大子序列和问题

本文探讨了最大连续子数列和的经典算法问题,通过四种不同算法逐步优化解决方案,复杂度从O(N^3)至O(N),并介绍了算法4作为联机算法的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最大连续子数列和一道很经典的算法问题,给定一个数列,其中可能有正数也可能有负数,我们的任务是找出其中连续的一个子数列(不允许空序列),使它们的和尽可能大。我们一起用多种方式,逐步优化解决这个问题。
例:
输入{ -2, 11, -4, 13, -5, -2 }时,答案为 20 (从A2到 A4).
算法1:

#include <stdio.h>
//N是数组长度,A是待计算的数组,放在全局区是因为可以开很大的数组
int N, A[1024];
int MaxSumsequenceSum(const int A[],int N);
int main()
{
    //输入数据
    scanf("%d", &N);
    for(int i = 1; i <= N; i++)
        scanf("%d", &A[i]);

    printf("%d\n",MaxSumsequenceSum(A,N));
    return 0;
}
int MaxSumsequenceSum(const int A[],int N)
{
    int ThisSum,MaxSum,i,j,k;
    MaxSum=0;
    for( i = 1; i <= N; i++)
        for( j = i; j <= N; j++)
         {
            ThisSum = 0;
            for( k = i; k <= j; k++)
            ThisSum+=A[k];

            if(ThisSum>MaxSum)
            MaxSum=ThisSum;
        }
     return  MaxSum;
}

算法2:

int MaxSumsequenceSum(const int A[],int N)
{
    int ThisSum,MaxSum,i,j;
    MaxSum=0;
    for( i = 1; i <= N; i++)
    {
        ThisSum=0;
        for( j = i; j <= N; j++)
         {
              ThisSum+=A[j];

            if(ThisSum>MaxSum)
            MaxSum=ThisSum;
        }
     return  MaxSum;
}

算法3:

static int MaxSubSum(int A[], int left, int right){
    int maxLeftSum, maxRightSum;
    int maxLeftBorderSum, maxRightBorderSum;
    int leftBorderSum, rightBorderSum;

    if(left == right)
        if(A[left] > 0)
            return A[left];
        else
            return 0;

    int mid = (left + right) / 2, i;
    maxLeftSum = MaxSubSum(A, left, mid);
    maxRightSum = MaxSubSum(A, mid + 1, right);

    maxLeftBorderSum = 0, leftBorderSum = 0;
    for(i = mid; i >= left; i--){
        leftBorderSum += A[i];
        if(leftBorderSum > maxLeftBorderSum)
            maxLeftBorderSum = leftBorderSum;
    }

    maxRightBorderSum = 0, rightBorderSum = 0;
    for(i = mid + 1; i <= right; i++){
        rightBorderSum += A[i];
        if(rightBorderSum > maxRightBorderSum)
            maxRightBorderSum = rightBorderSum;
    }

    return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}

算法4:

int MaxSumsequenceSum(const int A[],int N)
{
    int ThisSum,MaxSum , j ;
    ThisSum=MaxSum=0;
    for( j = i; j <= N; j++)
         {
                       ThisSum+=A[j];

            if(ThisSum>MaxSum)
            MaxSum=ThisSum;
     else if(ThisSum<0)
           ThisSum=0;
        }
     return  MaxSum;

}

四种算法的复杂度分别为O(N^3), O(N^2) , O(NlogN) , O( N);

其中算法3采用的是”分治(divide-and-conquer)策略. 其想法是把问题分成两个大致相等的子问题,然后递归的对他们求解,这是”分”部分,”治”阶段将两个子问题的解合并到一起并可能在做些少量的附加工作,最后的到问题的解;

算法4的一个附带优点是:它只对数据进行一次扫描,一旦A[i]被读入并处理,它就不再被记忆。因此,如果数组在磁盘上,它就可以被顺序读入,在主存中不必存储数组的任何部分。不仅如此,在任意时刻,算法都能对它已经读出子序列问题的正确答案(其他算法不具有这个特性), 具有这种特性的算法叫做联机算法( online algorithm),仅需要常量空间并以线性时间运行的联机算法几乎是完美的算法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值