编程之美-2.14-求数组的子数组之和的最大值
这个以前写过,见求数组的最长子数组之和的最大值
这里说一下后面扩展题目。
1. 简述
1) 如果数组首尾相连,即允许找到一组数字(A[i],···,A[n-1], A[0],···, A[j]),请使其和最大,怎么办?
2) 如果题目要求返回最大子数组的位置,算法应该如何改变?还能保持O(N)的复杂度么?
2. 思路
第一个问题,书上给出了解答,即分为首尾相连和首尾不连两种情况,对于首尾不连的情况,按照前面的思路就可以了,对于首尾相连的情况,那么必然包含A[N-1]与A[0],然后从A[0]向后找最大的一段(按照不连的方法),从A[N-1]向前找最大的一段(按照不连的方法),然后得到A[0]-A[j] 与 A[i]-A[N-1],如果j=<i,两段不重合,两端连起来就是解答;如果j>i,两段重合,那么整个数组就是解答。这里我要说一下,关于两段重合的情况,当重合的时候,为什么说整个数组就是解答呢?这个点上我有质疑,因为假设数组为1,2,3,4,-1,4,3,2,1,那么左边最大的一段是A[0]-A[N-1],右边最大的一段还是A[0]-A[N-1]那么按照书上的说法,此时重合,就是最大子数组为A[0]-A[N-1],实际上应该是去掉中间的-1的。
针对上面的问题最稳妥的方法应该是每次循环移位数组一次,然后按照首尾不连的方法求最大和,这N长度的数组,移位就是N种情况,每种情况O(N)的复杂度,一共是O(N^2)的复杂度。
第二个问题,应该很容易,每次更新开始位置和结束位置即可。
3. 参考
编程之美,2.14节,求数组的子数组之和的最大值