最大子序列和的线性时间解法
2015-03-12 14:57
323 查看
问题描述:给定整数A1,A2,...An(可能有负数)。求
![](http://img.blog.csdn.net/20150313202038233?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2Vud3VjaGlnZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
的最大值。(如果所有的整数都是负数,则最大子序列和为0。)
程序代码:
解释:
1.最大子序列的第一个元素不会是负的。即,如果a[i]是负的,那么它不可能是最大子序列的起点。因为任何用a[i]开头的序列,此时都不如用a[i+1]开头的序列和大。
2.同理,任何负的子序列都不可能是最优子序列的前缀。即,如果我们在内循环中检测到a[i]到a[j]的和是负的,那么我们可以推进i,关键的结论是我们不光可以推进到i+1,实际上我们可以直接推进到j+1。说明:令p是i+1到j之间的任何一个下标,因为j下标是第一个使从a[i]开始的序列变负的下标,所以,从a[i]到a[p]的序列和为正数。也就是说任何从p开始的子序列,都不如这个序列再加上a[i]到a[p-1]这个序列的和大。所以我们可以直接推进到j+1。
通过这个例子我们可以发现,许多聪明的算法,运行时间是明显的,本例是O(N),但是正确性不是那么明显。
的最大值。(如果所有的整数都是负数,则最大子序列和为0。)
程序代码:
int maxSubSum(const vector<int>&a) { int maxSum = 0; int thisSum = 0; for(int i = 0;i < a.size();i++) { thisSum += a[i];//新读取一个数 if(thisSum > maxSum)//这次的结果比最大序列还大 { maxSum = thisSum; } if(thisSum < 0)//推进i { thisSum = 0; } } return maxSum; }
解释:
1.最大子序列的第一个元素不会是负的。即,如果a[i]是负的,那么它不可能是最大子序列的起点。因为任何用a[i]开头的序列,此时都不如用a[i+1]开头的序列和大。
2.同理,任何负的子序列都不可能是最优子序列的前缀。即,如果我们在内循环中检测到a[i]到a[j]的和是负的,那么我们可以推进i,关键的结论是我们不光可以推进到i+1,实际上我们可以直接推进到j+1。说明:令p是i+1到j之间的任何一个下标,因为j下标是第一个使从a[i]开始的序列变负的下标,所以,从a[i]到a[p]的序列和为正数。也就是说任何从p开始的子序列,都不如这个序列再加上a[i]到a[p-1]这个序列的和大。所以我们可以直接推进到j+1。
通过这个例子我们可以发现,许多聪明的算法,运行时间是明显的,本例是O(N),但是正确性不是那么明显。
相关文章推荐
- 求最大子序列的线性时间复杂度的解法的理解
- 线性时间求解最大子序列和——HDU1003
- leetCode解题报告之O(n)线性时间求最大子序列和(Maximum Subarray)
- 最大子序列和的线性时间算法
- 最大子段和:线性序列的最大子段和的三种解法
- 求解最大子序列和问题的线性时间算法
- 线性时间内求最大子数组和
- 最大连续子数组积的线性解法
- Manacher算法 线性时间求最大回文子串长度
- 将m,n(m>n)的连续自然数序列,打乱顺序重新排列,随机取出一个数,试问取出的这个数是多少?使用一种解法,时间复杂度O(m-n),空间复杂度O(1)
- 算法导论第三版第四章 最大子数组和的三种解法(暴力、教材分治法、线性解法)
- 阿里巴巴面试算法题目:有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间
- LeetCode383. Ransom Note优雅解法(线性时间复杂度)
- 线性时间实现最大间隙问题
- 大数据面试题求解:给定n个实数 ,求着n个实数在实轴上向量2个数之间的最大差值,要求线性的时间算法(最大间隙问题)
- 在线性级别时间内找出无序序列中的第k个元素
- Python时间序列分析--从线性模型到GARCH模型
- 算法导论第三版第四章 最大子数组和的三种解法(暴力、教材分治法、线性解法)
- 算法-子数组连续序列最大和其时间复杂度如何从O(n^3)到O(n)
- 选择问题:线性时间内找到序列的第k小的元素