zoukankan      html  css  js  c++  java
  • 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 }

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

  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/Hello-Nolan/p/13542978.html
Copyright © 2011-2022 走看看