求子数组之和的最大值——编程之美 2.14 扩展问题 正确实现
2014-09-02 22:59
459 查看
使用动态规划求最大子数字和:
s[i]表示data[i~n-1]以元素i开始的最大子数组和,a[i]表示data[i~n-1]中的最大子数组和 ; s[i]=max(s[i+1]+data[i], data[i]); a[i]=max(a[i+1], s[i]); 由于数组s,a递推的时候,都只用到数组的前一个变量,所以可以用滚动数组节省空间。
扩展问题:
1) 如果数组首尾相连,即允许找到一组数字(A[i],···,A[n-1], A[0],···, A[j]),请使其和最大,怎么办?(书中答案错误,可以使用旋转数组的方法,时间复杂度n2,本文参考别人的想法,实现的算法复杂度为n)
2) 如果题目要求返回最大子数组的位置,算法应该如何改变?还能保持O(N)的复杂度么?
具体实现及思路如下:
#include <cstdio> /* 使用动态规划求最大子数字和: s[i]表示data[i~n-1]以元素i开始的最大子数组和,a[i]表示data[i~n-1]中的最大子数组和 ; s[i]=max(s[i+1]+data[i], data[i]); a[i]=max(a[i+1], s[i]); 由于数组s,a递推的时候,都只用到数组的前一个变量,所以可以用滚动数组节省空间。 */ int maxSum(int data[], int n) { int s = data[n-1]; int a = data[n-1]; for(int i = n-2; i>=0; i--) { if(s<0) s=0; s+=data[i]; if(s > a) a = s; } return a; } /* 如果要求返回最大子数组和的位置,如何处理? 使用curEnd记录当前最大字数组和的结束位置, 当s(以元素i开始的最大子数组和) 小于零时,更新curEnd字数组末端标记, 当a(当前的最大子数组和)发生变化时,更新最大字数组的标记Start,End */ int maxSum2(int data[], int n,int &start, int &end) { int s = data[n-1]; int a = data[n-1]; int curEnd = n-1; start = end = n-1; for(int i = n-2; i>=0; i--) { if(s<0) { s=0; curEnd = i; } s+=data[i]; if(s > a) { a = s; start = i; end = curEnd; } } return a; } /* 如果数组arr[0],…,arr[n-1]首尾相邻,也就是允许找到一段数字arr[i],…,arr[n-1],arr[0],…,a[j],使其和最大,该如何? 编程之美的答案的思路有问题,详见: http://www.ahathinking.com/archives/120.html 参考该文算法,可知在允许数组跨界(首尾相邻)时,最大子数组的和为下面的最大值 Maxsum={ 原问题的最大子数组和;数组所有元素总值-最小子数组和 } */ int maxSum3(int data[], int n) { int maxs = data[n-1]; int maxa = data[n-1]; int sumAll = data[n-1]; int mins = data[n-1]; int mina = data[n-1]; for(int i = n-2; i>=0; i--) { sumAll+=data[i]; if(maxs<0) maxs=0; maxs+=data[i]; if(maxs > maxa) maxa = maxs; if(mins>0) mins=0; mins+=data[i]; if(mins < mina) mina = mins; } int maxa2 = sumAll-mina; return maxa>maxa2?maxa:maxa2; } int main() { /* int d[]={ -4,-5,-6,-1,-5,-9 };*/ int d[]={ 8,-10,60,3,-1,-6 }; int s,e; int res = maxSum3(d,6); printf("%d\n",res); }
相关文章推荐
- 求子数组之和的最大值——编程之美 2.14 扩展问题 正确实现
- 编程之美2.14扩展问题1 求子数组和的最大值(首尾可以相连)
- 编程之美2.14扩展问题1 求子数组和的最大值(首尾可以相连)
- 编程之美2.14扩展问题1 求子数组和的最大值(首尾可以相连)
- 编程之美2.14扩展问题2 求数组的子数组之和的最大值并给出子数组的起始终止位置
- 编程之美2.14扩展问题2 求数组的子数组之和的最大值并给出子数组的起始终止位置
- 编程之美2.14 子数组之和的最大值 扩展问题(首尾相连)
- [编程之美2.14]求子数组之和的最大值
- 《编程之美》读书笔记(十二):“求数组的子数组之和的最大值”扩展问题
- 编程之美寻找数组中的最大值和最小值以及扩展问题
- 编程之美2.10寻找数组中的最大值和最小值扩展问题Java版
- 编程之美2.14 求子数组和的最大值(首尾相连)
- 编程之美 2.14 数组的子数组之和的最大值 扩展题2
- 算法导论C语言实现: 分治策略 -- 最大子数组问题
- 编程之美系列之求子数组的最大乘积
- 编程之美2.14 求数组的子数组之和的最大值
- 编程之美系列之求子数组的连续最大积
- 编程之美2.14 求数组的子数组之和的最大值
- 编程之美系列之求子数组的最大和(续)
- 编程之美系列之求子数组的连续最大和