求数组的子数组之和的最大值
来源:互联网 发布:sql数据库设计工具 编辑:程序博客网 时间:2024/05/18 08:45
求数组的子数组之和的最大值
提出问题:
一个有N个整数元素的一维数组(A[0],A[1],A[2]……A[n-1]),那么子数组之和的最大值是什么?
例如:-2 5 3 -6 4 -8 6 maxsum=8
解法一:
我们先明确题意,
1:题目说的子数组是连续的
2:题目只需要求和,并不需要返回子数组的具体位置
3:数组的元素是整数,所以数组可能包括正整数,零,负整数。
举几个例子:
eg1: 1 -2 3 5 -3 2 maxsum=8
eg2: 0 -2 3 5 -1 2 maxsum=9
eg3: -8 -9 -2 -5 -3 maxsum=-2
最直接的方法就是找出所有的子数组,然后求其和,取最大。如果每个子数组都遍历求和,该方法的复杂度为O(N^3),仔细考虑,在遍历过程中,这些子数组的和是有重复计算的:下标i与j之间的区间和Sum[i,j]=Sum[i,j-1]+arr[j]。于是子数组和的求法不必每次都遍历,算法复杂度可以降为O(N^2)。代码如下:
int Maxsum1(int *array,int n){int max=-INF;int sum;int i,j;for(i=0;i<n;i++){sum=0;for(j=i;j<n;j++){sum+=array[j];if(sum>max)max=sum;}}return max;}
解法二:DP
我们考虑最后一个元素arr[n-1]与最大子数组的关系,有如下三种情况:
- arr[n-1]单独构成最大子数组
- 最大子数组以arr[n-1]结尾
- 最大子数组跟arr[n-1]没关系,最大子数组在arr[0-n-2]范围内,转为考虑元素arr[n-2]
从上面我们可以看出,问题分解成了三个子问题,最大子数组就是这三个子问题的最大值,现假设:
- 以arr[n-1]为结尾的最大子数组和为End[n-1]
- 在[0-n-1]范围内的最大子数组和为All[n-1]
如果最大子数组跟最后一个元素无关,即最大和为All[n-2](存在范围为[0-n-2]),则解All[n-1]为三种情况的最大值,即All[n-1] = max{ arr[n-1],End[n-1],All[n-2] }。从后向前考虑,初始化的情况分别为arr[0],以arr[0]结尾,即End[0] = arr[0],最大和范围在[0,0]之内,即All[0]=arr[0]。
int Maxsum2(int * array, int n){ int End[MAX] = {-INF}; int All[MAX] = {-INF}; End[0] = All[0] = array[0]; for(int i = 1; i < n; ++i) { End[i] = max(End[i-1]+arr[i],arr[i]); All[i] = max(End[i],All[i-1]); } return All[n-1];}
仔细看上面DP方案的代码,End[i] = max{arr[i],End[i-1]+arr[i]},如果End[i-1]<0,那么End[i]=arr[i],什么意思?End[i]表示以i元素为结尾的子数组和,如果某一位置使得它小于0了,那么就自当前的arr[i]从新开始,且End[i]最初是从arr[0]开始累加的,所以这可以启示我们:我们只需从头遍历数组元素,并累加求和,如果和小于0了就自当前元素从新开始,否则就一直累加,取其中的最大值便求得解。int Maxsum3(int *array,int n){int max=-INF;int sum=0;for(int i=0;i<n;i++){if(sum<0)sum=array[i];elsesum+=array[i];if(sum>max)max=sum;}return max;}
其实上面的方法虽说是从DP推导出来的,但是写完发现也是很直观的方法,求最大和,那就一直累加呗,只要大于0,就说明当前的“和”可以继续增大,如果小于0了,说明“之前的最大和”已经不可能继续增大了,就从新开始,如此这样。
2 0
- 求数组的子数组之和最大值
- 求数组子数组之和的最大值
- 2.14 求子数组之和的最大值
- 求数组的子数组之和的最大值
- [算法题] 求数组的子数组之和的最大值
- [算法题] 求数组的子数组之和的最大值
- [算法题] 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 2.14求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的子数组之和的最大值
- 求数组的连续子数组之和的最大值
- 求数组的子数组之和的最大值 .
- Thinking In Java琐碎知识点摘要(二)
- java中到底有没有指针
- struts2执行流程
- 调用WebService异常。
- C++ c创建txt文件
- 求数组的子数组之和的最大值
- 你不知道的Java秘密
- fedora20 KDE中文的实现
- Eclipse ino版安装apata插件时No more handles [Could not detect registered XULRunner to use]
- openssl 漏洞升级
- struts2拦截器(拦截指定方法)
- 黑马程序员 空中网面试2
- cc2530晶振与时钟
- thrift、proto buf与Avro区别