算法-最长子序列和C/C++实现(三个复杂度)

最长子序列和的问题非常easy:

就是一个数组,求出当中当中连续的某一段和,而这一段和是全部的连续段和的最大的值。求出这个值。


先说复杂度最高的:O(n3)

直接上代码,非常easy的:

//
//  main.cpp
//  SumSequence
//
//  Created by Alps on 14-7-23.
//  Copyright (c) 2014年 chen. All rights reserved.
//

#include <iostream>
using namespace std;

int MaxSubsequenceSum(const int A[], int N){
    int ThisSum, MaxSum, i, j, k;
    MaxSum = 0;
    for(i = 0; i < N; i++){
        for(j = i; j < N; j++){
            ThisSum = 0;
            for (k = i; k < j; k++) {
                ThisSum += A[k];
            }
            MaxSum = ThisSum > MaxSum ? ThisSum: MaxSum;
        }
    }
    return MaxSum;
}

int main(int argc, const char * argv[])
{

    int A[] = {1, 2, -5, 2, 5, 1, 8, -4};
    int N = sizeof(A)/sizeof(int);
//    printf("%d\n",N);
    int MaxSum = MaxSubsequenceSum(A, N);
    printf("%d\n",MaxSum);
    return 0;
}

这个事实上非常easy,第一层for循环是i从头開始遍历。第二层for是j从i遍历到尾。第三层就是算i到j的这一段的和。

时间复杂度是O(n3).

以下说一个O(n2)的:

代码例如以下:

//
//  main.cpp
//  SumSequencen2
//
//  Created by Alps on 14-7-23.
//  Copyright (c) 2014年 chen. All rights reserved.
//

#include <iostream>
using namespace std;

int MaxSubSequenceSum(const int A[], int N){
    int MaxSum, ThisSum, i, j;
    MaxSum = 0;
    for (i = 0; i < N; i++) {
        ThisSum = 0;
        for (j = i; j < N; j++) {
            ThisSum += A[j];
            MaxSum = MaxSum > ThisSum ? MaxSum : ThisSum;
        }
    }
    return MaxSum;
}

int main(int argc, const char * argv[])
{
    int A[] = {1, 2, -5, 2, 5, 1, 8, -4};
    int N = sizeof(A)/sizeof(int);
    //    printf("%d\n",N);
    int MaxSum = MaxSubSequenceSum(A, N);
    printf("%d\n",MaxSum);
    
    return 0;
}
这个也比較好理解,第一层循环就是i从头到尾遍历,第二层循环是j从i遍历到尾,在遍历过程中不断检測ThisSum的大小,取Max(ThisSum, MaxSum)的数,并赋值给MaxSum,这样就能够知道MaxSum是多少了~


另一个方法复杂度是O(nlogn)可是这个算法比較麻烦,代码也比較麻烦,我这里没有写~想学的能够去《数据结构与算法分析》来学习。


这里有一个O(n)级别的算法来解决问题!!!:请看代码:


//
//  main.cpp
//  SumSequencen
//
//  Created by Alps on 14-7-23.
//  Copyright (c) 2014年 chen. All rights reserved.
//

#include <iostream>

using namespace std;

int MaxSubSequenceSum(const int A[], int N){
    int MaxSum, ThisSum, i;
    MaxSum = A[0];
    ThisSum = 0;
    for (i = 0; i < N; i++) {
        ThisSum += A[i];
        MaxSum = ThisSum > MaxSum ? ThisSum: MaxSum;
        if (ThisSum < 0) {
            ThisSum = 0;
            continue;
        }
    }
    return MaxSum;
}

int main(int argc, const char * argv[])
{
    int A[] = {1, 2, -5, 2, 5, 1, 8, -4};
    int N = sizeof(A)/sizeof(int);
    //    printf("%d\n",N);
    int MaxSum = MaxSubSequenceSum(A, N);
    printf("%d\n",MaxSum);
    return 0;
}

O(n)级别的这类算法算是比較完美的算法了。我对这个算法的理解就是,在一个数组里,有非常多非常多段,这些段都有一个和,最小的段是一个元素,而最大的序列和肯定是一个段,或者是两个段的和,和就是加上一个正数就变大,所以当一个段是负数的时候,我就直接抛弃掉了~(除非全部都是负数,就找一个最大的。)

所以就有了上面的算法。。不懂的请留言~


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值