下面介绍一个线性的算法,这个算法是许多聪明算法的典型:运行时间是明显的,但是正确性则很不明显(不容易理解)。

//线性的算法O(N)

long maxSubSum4(const vector<int>& a)
{
long maxSum = 0, thisSum = 0;
for (int j = 0; j < a.size(); j++)
{
thisSum += a[j];
if (thisSum > maxSum)
maxSum = thisSum;
else if (thisSum < 0)
thisSum = 0;
}
return maxSum;
}

很容易理解时间界O(N)
是正确的,但是要是弄明白为什么正确就比较费力了。其实这个是算法二的一个改进。分析的时候也是i代表当前序列的起点,j代表当前序列的终点。如果我们不需要知道最佳子序列的位置,那么i就可以优化掉。

    重点的一个思想是:如果a[i]是负数那么它不可能代表最有序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过用a[i+1]作为起点来改进。类似的有,任何的负的子序列不可能是最优子序列的前缀。例如说,循环中我们检测到从a[i]到a[j]的子序列是负数,那么我们就可以推进i。关键的结论是我们不仅可以把i推进到i+1,而且我们实际可以把它一直推进到j+1。

举例来说,令p是i+1到j之间的任何一个下标,由于前面假设了a[i]+…+a[j]是负数,则开始于下标p的任意子序列都不会大于在下标i并且包含从a[i]到a[p-1]的子序列对应的子序列(j是使得从下标i开始成为负数的第一个下标)。因此,把i推进到j+1是安全的,不会错过最优解。注意的是:虽然,如果有以a[j]结尾的某序列和是负数就表明了这个序列中的任何一个数不可能是与a[j]后面的数形成的最大子序列的开头,但是并不表明a[j]前面的某个序列就不是最大序列,也就是说不能确定最大子序列在a[j]前还是a[j]后,即最大子序列位置不能求出。但是能确保maxSum的值是当前最大的子序列和。这个算法还有一个有点就是,它只对数据进行一次扫描,一旦a[j]被读入处理就不需要再记忆。它是一个联机算法。

最大子序列和(O(n))的更多相关文章

  1. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  2. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  3. [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

  4. [LeetCode] Is Subsequence 是子序列

    Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...

  5. [LeetCode] Wiggle Subsequence 摆动子序列

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...

  6. [LeetCode] Increasing Triplet Subsequence 递增的三元子序列

    Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...

  7. [LeetCode] Distinct Subsequences 不同的子序列

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  8. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  9. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

  10. 51nod1134(最长递增子序列)

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1134 题意: 中文题诶~ 思路: 直接暴力的话时间复杂度为 ...

随机推荐

  1. Swift中的HTTP请求

    iOS开发中大部分App的网络数据交换是基于HTTP协议的.本文将简单介绍在Swift中使用HTTP进行网络请求的几种方法. 注意:网络请求完成后会获得一个NSData类型的返回数据,如果数据格式为J ...

  2. BI案例:某公司BI系统的九大主题分析

    1.KPI分析 KPI分析按照管理层次和时间纬度对指标进行汇总统计及分析展示,以适应各级领导的管理需求.在某公司,KPI不仅只是一个数据展示,而且已经成为一个内部考核指标的监控平台.各级领导每天上班的 ...

  3. oracle group by中cube和rollup字句的使用方法及区别

    oracle group by中rollup和cube的区别:  Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是ROLLUP(A, B, C)的话,先 ...

  4. HttpSessionBindingListener和HttpSessionAttributeListener区别 - gengkunpeng的专栏 - 博客频道 - CSDN.NET

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 HttpSession ...

  5. C#写入登陆Cookies

    protected void Page_Load(object sender, EventArgs e) { //打开登录页面时获取客户端cookie值并写入前台控件中 HttpCookie cook ...

  6. 【jmeter】搭建持续集成接口测试平台(Jenkins+Ant+Jmeter)

    一.环境准备: 1.JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.Jmeter:http://jme ...

  7. runliuv, 安卓查看WIFI密码

    用RE查看data/misc/wifi/wpa_supplicant.conf或者其他文件名以.conf结尾的文件

  8. 使用 OWIN 作为 ASP.NET Web API 的宿主

    使用 OWIN 作为 ASP.NET Web API 的宿主 ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动 设备)的 HTTP 服务. ASP.NET ...

  9. VS使用技巧

    1.VS帮助安装 VS2010为例==>注意,长时间未进行帮助安装,不过以下流程应该没有什么问题.如有问题,还请谅解... 2.VS即时窗口的应用 VS2010为例==>即时窗口的用法调试 ...

  10. eclipse下编译hadoop源代码(转)

    hadoop是一个分布式存储和分布式计算的框架.在日常使用hadoop时,我们会发现hadoop不能完全满足我们的需要,我们可能需要修改hadoop的源代码并重新编译.打包. 下面将详细描述如何从sv ...