分享一下自己的“01-复杂度2 Maximum Subsequence Sum”作答(看完mooc后写的)

文章介绍了如何解决寻找给定整数序列中具有最大和的连续子序列的问题。它提供了四种不同复杂度的C语言实现,从O(N^3)到O(N),并特别强调了O(N)解决方案的效率,该方案在100000个随机数的情况下运行时间为10ms。此外,文章还指出了特殊情况,如全负数序列时应返回序列首尾,以及包含前导零的情况。
摘要由CSDN通过智能技术生成

Given a sequence of K integers { N1​, N2​, ..., NK​ }. A continuous subsequence is defined to be { Ni​, Ni+1​, ..., Nj​ } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

 以上是原题内容。

需要注意的是:

1)相比输出最大子列和,该题需要输出最大子列和的首尾数字,注意不是下标!(一开始以为是下标25分只拿了3分)。

2)有一个1分的要求是最大子列和含有前面一段0,需要将输出结果的最大子列和首个数字包括这个0(这一问题没读懂折腾了好久给自己整笑了hh)。

3)如果全是负数,输出结果的头尾应该是序列的头尾;如果全是负数和零,输出结果最大子列和头尾应该都是0。

跟着mooc的视频试了一下o(N^3)、o(N^2)、o(NlogN)、o(N)四种算法;在不输出子列和头尾的情况下,o(N^3)的算法测试OJ罢工了,o(N^2)在100000个随机数的时候用时3334ms,o(NlogN)在100000个随机数用时12ms,o(N)在100000个随机数下用时10ms。

以下是使用o(N)复杂度的算法解这道题。


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

int *MaxSubseqSum4(int *n,int k);

int main(){
    int *result,k,n[100000]={0};
    scanf("%d",&k);
    for(int i=0;i<k;i++){
        scanf("%d",&n[i]);
    }
    result=MaxSubseqSum4(n,k);

    printf("%d %d %d",result[0],result[1],result[2]);

    free(result);
    return 0;
}

int* MaxSubseqSum4(int *n,int k){
    int thissum=0,maxsum=0,cnt=0;
    int *result=(int*)malloc(sizeof(int)*3);
    result[1]=0;
    bool exist_0=false;
    for(int i=0;i<k;i++){
        thissum+=n[i];
        cnt++;
        if(thissum>maxsum){
            maxsum=thissum;
            result[2]=n[i];
            result[1]=n[i-cnt+1];
        }else if(thissum<0){
            thissum=0;
            cnt=0;
        }else if(thissum==0){
            exist_0 = true;
        }
    }
    result[0]=maxsum;
    if(maxsum==0&&exist_0){
        result[1]=0;
        result[2]=0;
    }else if(maxsum==0){
        result[1]=n[0];
        result[2]=n[k-1];
    }
    return result;
}

 以下是前面讲的四种算法复杂度的C语言实现,按o(N^3)、o(N^2)、o(NlogN)、o(N)顺序分别是MaxSubseqSum(1-4)四个函数。

#include<stdio.h>

int max(int a,int b,int c){
    return a>b?(a>c?a:c):(b>c?b:c);
}
int DivideandConquer(int *n,int left,int right);

int MaxSubseqSum1(int *n,int k);
int MaxSubseqSum2(int *n,int k);
int MaxSubseqSum3(int *n,int k);
int MaxSubseqSum4(int *n,int k);

int main(){
    int sum,k,n[100000]={0};
    scanf("%d",&k);
    for(int i=0;i<k;i++){
        scanf("%d",&n[i]);
    }
    sum=MaxSubseqSum4(n,k);
    printf("%d",sum);
    return 0;
}

int MaxSubseqSum4(int *n,int k){
    int thissum=0,maxsum=0;
    for(int i=0;i<k;i++){
        thissum+=n[i];
        if(thissum>maxsum){
            maxsum=thissum;
        }else if(thissum<0){
            thissum=0;
        }
    }
    return maxsum;
}

int DivideandConquer(int *n,int left,int right){
    int maxleftsum=0,maxrightsum=0;
    int maxleftbordersum=0,maxrightbordersum=0;
    int leftbordersum=0,rightbordersum=0;
    int center=(left+right)/2;
    
    if(left==right){
        if(n[left]>0) return n[left];
        else return 0;
    }
    maxleftsum=DivideandConquer(n,left,center);
    maxrightsum=DivideandConquer(n,center+1,right);
    
    for(int i=center;i>=left;i--){
        leftbordersum+=n[i];
        if(leftbordersum>maxleftbordersum) maxleftbordersum=leftbordersum;
    }
    for(int i=center+1;i<=right;i++){
        rightbordersum+=n[i];
        if(rightbordersum>maxrightbordersum) maxrightbordersum=rightbordersum;
    }
    
    return max(maxleftsum,maxrightsum,maxleftbordersum+maxrightbordersum);
}
int MaxSubseqSum3(int *n,int k){
    return DivideandConquer(n,0,k-1);
}




int MaxSubseqSum2(int *n,int k){
    int thissum=0,maxsum=0;
    for(int i=0;i<k;i++){
        thissum=0;
        for(int j=i;j<k;j++){
            thissum+=n[j];
            if(thissum>maxsum){
                maxsum=thissum;
            }
        }
    }
    return maxsum;
}

int MaxSubseqSum1(int *n,int k){
    int thissum=0,maxsum=0;
    for(int i=0;i<k;i++){
        for(int j=i;j<k;j++){
            thissum=0;
            for(int m=i;m<j;m++){
                thissum+=n[m];
                if(thissum>maxsum){
                    maxsum=thissum;
                }
            }
        }
    }
    return maxsum;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值