不同复杂度求解最大连续和
来源:互联网 发布:淘宝手机充值卡换现金 编辑:程序博客网 时间:2024/05/16 14:05
问题描述:
给定一个整数序列A[0],A[1], … , A[N-1],每个元素可正可负,求该序列中最大的连续和。
方法1 暴力求解法
这种方法最直接,暴力枚举每一个每一个连续片段的起点和终点,然后求相应
的和。其复杂度即为
算法描述为:
int maxx = A[0];for(int i=0; i<N; i++) for(int j=i; j<N; j++) { int sum = 0; for(int k=i; k<=j; k++) sum+=A[k]; maxx = sum>maxx ? sum:maxx; }
方法2 利用递推前缀和记录0−i 项的和
这种方法使用了已经计算的信息,减少了重复工作,使得复杂度降为
算法描述为:
S[0] = A[0];maxx= A[0];for(int i=1; i<N; i++) S[i] = S[i-1]+A[i];for(int i=1; i<N; i++) for(int j=i; j<N; j++) maxx = maxx>S[j]-S[i-1] ? maxx:S[j]-S[i-1];
方法3 采用二分法进行递归求解,进一步降低复杂度
这种方法可以有效降低复杂度,其复杂度为
代码如下:
// O(nlogn)复杂度int maxsum(vector<int>& A, int x, int y){ if(y-x==1) return A[x]; int m = x+(y-x)/2; int mx = maxsum(A, x, m); int my = maxsum(A, m, y); int maxx = mx>my ? mx:my; int v = 0, L = A[m-1], R = A[m]; /// 从分界点开始往左的最大连续和L,并保证L不减 for(int i=m-1; i>=x; i--) L = L>=(v+=A[i]) ? L:v; v = 0; /// 从接点点开始往右的最大连续和R,并保证R不减 for(int i=m; i<y; i++) R = R>=(v+=A[i]) ? R:v; return maxx>(L+R) ? maxx:L+R;}
方法4 优化方法2,并使复杂度变为线性
这种方法同样利用了前缀和,并且用mx记录前i项中最大的连续和,在一次遍历A的过程中同时更新mx和sum,从而使得复杂度
代码如下:
// O(n)复杂度int maxsum2(vector<int>& A){ int * sum = new int[A.size()]; int mx = A[0]; // or mx = INT_MIN; sum[0] = A[0]; for(int i=1; i<A.size(); i++) mx = mx>(sum[i]=sum[i-1]>0?sum[i-1]+A[i]:A[i]) ? mx:sum[i]; delete sum; return mx;}
这4种方法中以最后两种比较好用,而最后一种在一次遍历中同时更新了多个量,达到了算法的最优。这启发我们,在算法设计过程中,尽量充分利用已经计算的信息可以使得算法更加优化。
后记:
本质上第4种方法是一种DP。
其中sum[i]用来记录a[0]…a[i]的最大连续和。即
sum[0] = a[0];sum[i] = max(a[i], a[i]+sum[i-1]);
如果sum[i-1]为负数,那么sum[i]=a[i],否则sum[i]=sum[i-1]+a[i];
参考http://blog.csdn.net/newmemory/article/details/50821573
1 0
- 不同复杂度求解最大连续和
- 瞬间求解最大连续和
- C#连续区间最大和求解
- 动态规划求解数组连续最大和
- 求最大连续子列和的算法和时间复杂度的分析(包含四种不同时间复杂度的算法)
- 最大连续子序列和问题O(N)复杂度
- 动态规划求解最大连续子序列和
- 如何求解最大连续子序列的和
- golang动态规划求解最大连续子数组和
- 最大子段和算法 不同复杂度方法实现
- 不同时间复杂度实现最大子段和
- 最大子序列和的四种不同复杂度实现
- 最大子序列和的四种不同复杂度实现
- 连续子数组最大和或最大子段和的求解算法及其正确性
- 最大子序列和的求解(时间复杂度O(N))
- 最大子序列和问题的求解(时间复杂度为O(N))
- 归纳法求解最大连续子序列
- 求解最大连续子数组的算法
- linux 命令
- 各种View的使用技巧和注意点
- Window.open()方法参数详解
- 红茶一杯话Binder(传输机制篇_上)
- Android官方开发文档Training系列课程中文版:线程执行操作之创建多线程管理器
- 不同复杂度求解最大连续和
- 如何搭建运营级的网络直播平台
- 基于Android Studio的内存泄漏检测与解决
- win10安装方法(可以不需要激活)
- if elseif elseif elseif else...
- jQuery常见知识要点
- 基于Opencv2.4.11+OpenGL(Qt5.6.0)实现增强现实(二)
- 基于workerman的聊天室
- html5 存储详解