• 31. 最大连续子序列和(三)


    一. 最大子序列和-联机算法

    在前两篇博文中,我们了解了两种较差算法,和一种分治算法。下面我们讲解一个更好的方法:联机算法。这种算法的时间复杂度是 O(n)。这个方法也是解决这个问题的最好算法,因为无论如何,读取数据也要 n 次。

    1. 实例分析

    给定一组数据,data = (1, 4, -3, 7, -6, 10 )。

    (1)读取第一个元素 1,此时部分和为 1,大于 0, 说明此元素可以为最大值作出贡献,于是将其加入到子序列中。

    (2)接着读入第二个元素 4, 发现这个元素加上部分和等于 5, 大于 0 ,它也能够为最大值作出贡献,将其加入到子序列中。

    (3)接着读入第三个元素 -3, 我们发现这个元素是负的,但是它加上部分和等于 2, 大于 0 。虽然它拖了后腿,但是也不至于让部分和成为负的,因此也将其加入到子序列中。

    其余元素同理。

    我们考虑一个问题:假如读取了一个新元素,这个元素使得部分和小于 0 了,那么应该怎么处理?一个小于 0 的部分和,只会给我们的最大和拖后腿,却不能提供任何有价值的东西。到这一步,我们将部分和重置为 0 ,说明前面的元素前功尽弃了,我们要从它的下一个元素开始,重新计算部分和,看看其余子序列会创造新记录。如果到结尾,所有元素均已处理完毕,有了新的最大和,那么我们将最大和更新,否则最大和不变。

    2. 代码实现

     1 int max_sub_sum_online(const vector<int>& data) {
     2     const int MIN = numeric_limits<int>::min();
     3     int max_sum = MIN, partial_sum = 0;
     4 
     5     for (int i = 0; i < data.size(); ++i) {
     6         partial_sum = max(partial_sum, 0) + data[i];
     7         max_sum = max(partial_sum, max_sum);
     8     }
     9 
    10     return max_sum;
    11 }

    代码中没有什么难点。这说明了一个思想:真正好的方法,能够优雅的解决问题,不论是代码实现,还是算法思路,都很容易懂。

  • 相关阅读:
    Java五
    Java I/O流
    第二周学习笔记
    第一周学习笔记
    第六次作业修改版
    第六周作业
    java第四次作业(补)
    java第五次作业
    Java第三次作业
    java第二次作业
  • 原文地址:https://www.cnblogs.com/Hello-Nolan/p/13542978.html
Copyright © 2020-2023  润新知