最大子列和算法
来源:互联网 发布:会计电算化软件下载 编辑:程序博客网 时间:2024/05/01 17:34
作者:whj95
算法一:双边界单扫描
该算法为三变量三循环,
核心思想:分别设两个变量确立左边界和右边界,然后再用一个变量当做光标从左边界到右边界扫描求和。
伪码:
int maxsubseqsum(const int A[],int N){ 循环体(i,i < N,i++) 循环体(j=i,j < N;j++) 抛弃当前和 循环体(k=i;k<=j;k++) 维护当前和与最大和}
C++参考代码如下:
int maxsubseqsum(const int A[],int N){ int thissum = 0,maxsum = 0; for(int i = 0; i <N; i++) for(int j = i; j < N; j++) { thissum = 0;//每次更新边界抛弃之前的thisum值 for(int k = i; k <= j; k++) thissum += A[k]; if(thissum > maxsum) maxsum = thissum; } return maxsum;}
缺陷:所谓光标设置完全没有用,时间复杂度T(N) = O(N
算法二:单边界单扫描
该算法为双变量双循环,
核心思想:设一个变量为左边界,另一个变量从左边界往后扫描即可。
伪码:
int maxsubseqsum(const int A[],int N){ 循环体(i,i < N,i++) 抛弃当前和 循环体(j=i,j < N;j++) 维护当前和与最大和}
C++参考代码如下:
int maxsubseqsum(const int A[],int N){ int thissum = 0,maxsum = 0; for(int i = 0; i < N; i++) { thisnum = 0;//每次更新边界抛弃之前的thisum值 for(int j = i; j < N; j++) thissum += A[j]; if(thissum > maxsum) maxsum = thissum; } return maxsum;}
缺陷:时间复杂度为T(N) = O(N
算法三:分治法
图片源于浙大陈越老师的数据结构课件
可将问题分治,即分解为规模更小的类似的问题:每次将子列对半拆分,最大子列即为max(①最大左子列②最大右子列③横跨划分线的最大子列)
伪码:
int maxsubseqmax(int A[],int left,int right){ /*递归部*/ 递归基类 左子列递归,右子列递归 /*跨越中部的情况*/ 循环体 { 维护当前子列和与最大子列和和 }//中部向左最大子列 循环体 { 维护当前子列和与最大子列和和 }//中部向右最大子列 /*三分归一*/ 返回max(最大左子列,最大右子列,中部向左最大子列+中部向右最大子列)}
C++参考代码如下:
int maxsubseqsum(int A[],int left,int right){ /*递归基准*/ if(left == right) { if(A[left] > 0) return A[left]; else return 0; } /*左半边右半边递归*/ int center = (left + right) / 2; int maxLeftSum = maxsubseqsum(A,left,center); int maxRightSum = maxsubseqsum(A,center + 1,right); /*穿过中部的子列 = 中部往左最大子列+中部往右最大子列*/ int thisLeftBorderSum = 0,maxLeftBorderSum = 0; for(int i = center; i >= left; i--) { thisLeftBorderSum += A[i]; if(thisLeftBorderSum > maxLeftBorderSum) maxLeftBorderSum = thisLeftBorderSum; } for(int i = center + 1; i >= right; i++) { thisRightBorderSum += A[i]; if(thisRightBorderSum > maxRightBorderSum) maxRightBorderSum = thisRightBorderSum; } return max3(maxLeftSum,maxRightSum,maxLeftBorderSum + maxRightBorderSum);}/*三分归一*/int max3(int a,int b,int c){ int max = 0; if(a > b) max= a; else max = b; max = (max,c)?max:c; return max;}
缺陷:相比以上两种算法,该算法拥有足够优秀的时间复杂度T(N) = O(NlogN)。推导如下:T(N) = 2T(N/2)+cN = 2[2T(N/2
∵N/2
∴k = log
即T(N) = O(NlogN)
但由于算法四达到了线性时间,所以此算法还并非最优算法。其实该算法在递归基准中也蕴含了算法四的思想。
算法四:单变量在线处理
核心思想:最大子列和要求的是连续和最大。既然连续则扫到的当前子列可以看成一个数,而要求最大则每次维护的当前子列和不能为负(注:不是指单个元素不能为负),否则舍去。
伪码:
int maxsubseqsum(const int A[],int N){ 循环体 { 当前子列和 += A[i]; if(当前子列和>=0) 维护当前子列和与最大子列和 if(当前子列和<0) 舍去当前子列和(令当前子列和=0) }}
C++参考代码如下:
int maxsubseqsum(const int A[],int N){ int thissum = 0,maxsum = 0; for(int i = 0; i < N; i++) { thissum += A[i]; if(thissum > maxsum) maxsum = thissum; if(thissum < 0) thissum = 0; }}
缺陷:无。
该算法是此问题的终极算法,时间复杂度T(N) = O(N),仅为线性时间,而且其为在线处理,即突然切除后面的数据也能得出新子列的最大子列。
- 最大子列和算法
- 最大子列和
- 最大子列和
- 最大子列和
- 最大子列和
- 求最大子列和问题两种算法比较
- 求解最大子列和问题的四种算法
- 从最大子列和问题体会算法
- 数据结构与算法--求最大子列和问题
- 求最大子列和的四种算法
- 算法笔记-1-最大子列和-Maximum Subsequence Sum
- 最大子列和的四种算法比较
- 学习笔记:数据结构、算法::求最大子列和
- 最大子列和问题的不同实现算法
- 最大子列和(算法复杂度优化)
- 最大子列和问题
- 最大子列和问题
- 最大子列和问题
- hadoop单个数据节点的不同存储路径的存储策略源码分析
- [断点调试好助手]LLDB调试
- Dart Essentials(读书笔记)——这本书很大篇幅都在谈AngularDart,Zones概念没谈到
- Spring学习笔记——Sprin管理Bean的原理
- [BZOJ 1029][JSOI2007]建筑抢修
- 最大子列和算法
- sql left join的多表应用
- nginx配置文件详解
- Spark开发问题集锦
- grep命令的详细使用方法
- 网站怎么运转的
- 约瑟夫环问题
- 怎样教四岁的孩子学画画
- Android中如何解析JSON数据