DSAA之最大子序列之和问题(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LoveStackover/article/details/79956270

最大子序列之和的几种算法

  首先必须强调,笔者使用《DSAA》英文版有大量印刷错误,导致笔者浪费很多时间。所以建议对有疑惑的地方与别的版本对照。

1. 算法1

  常规解法,也就是穷举法:

//2_1.c
#include <stdio.h>
#include <stdlib.h>
#define handle_error(m) do{ perror(m);exit(-1);}while(0)




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


int main(void)
{
    int n;
    int * ptr;
    int i;
    scanf("%d",&n);

    if((ptr = calloc(n,sizeof(int))) == NULL)
        handle_error("calloc");
    for(i =0; i<n; i ++){
        scanf("%d",(ptr+i));
    }

    printf("max sum subsquence : %d\n",maxsubsquencesum(ptr,n));
    return 0;


}

  结果如下:

[root@localhost ~]# ./2_1         
5
-1 2 -1 2 4 
max sum subsquence : 7

  
  分析该算法的时间复杂度,由于明显具有套嵌的三个for循环,且最内层的语句的时间复杂度为O(1),所以最坏情况下该程序的时间复杂度为O(n3)。该算法也是笔者这种没有系统学过算法的所接受的穷举法。

2. 算法2

  修改maxsubsquencesum函数如下:

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

  笔者查阅了下网上其他人的理解,发现都是后验逻辑,采用举例子的方式理解。这种方式理解方式恐怕遇到新的问题就不知道怎么解了,因为是根据结果来理解过程。根据《DSAA》的提示,观察第一种解法中的

for(k=i;k<=j;k++){
                thissum+=*(ptr+k);
            }

  其对应的数学表达式为:k=ij(ptr+k),其值等于thissum(j),根据k=ij(ptr+k)=k=ij1(ptr+k)+(ptr+j),得到

thissum(j)=thissum(j1)+(ptr+j)

  用代码去表示上面的递推公式为:thissum =thissum+*(ptr+j);,然后其时间复杂度因为有两个for循环,所以为O(n2)

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页