【数据结构第一周】最大子列和问题整理
题目地址:http://www.patest.cn/contests/mooc-ds/01-1
算法一:暴力,直接计算出所有子列和,然后比较,显然复杂度炸裂,O(N^3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | int MaxSubseqSum1( int A[], int N) { int ThisSum; int MaxSum = 0; int i,j,k; for (i = 0; i < N; ++i) //i是子列左端的位置 { for (j = i; j < N; ++j) //j是子列右端的位置 { ThisSum = 0; //A[i]到A[j]的子列和 for (k = i; k < j ; ++k) { ThisSum += A[k]; if (ThisSum > MaxSum) { MaxSum = ThisSum; } } } } return MaxSum; } |
算法二:优化第三层循环,将复杂度降到O(N^2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int MaxSubseqSum2( int A[], int N) { int ThisSum; int MaxSum = 0; int i,j; for (i = 0; i < N; ++i) //i是子列左端的位置 { ThisSum = 0; //A[i]到A[j]的子列和 for (j = i; j < N; ++j) //j是子列右端的位置 { ThisSum += A[j]; //对于相同的i,不同的j,只要在j-1的基础上累加上1项即可 if (ThisSum > MaxSum) { MaxSum = ThisSum; } } } return MaxSum; } |
算法三:分而治之,把数组从中间分成两部分,然后递归地解决左右两边,最后考虑跨越边界的最大值。
复杂度的推算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | int MaxSubseqSum3( int A[], int x, int y) { if (y-x==1) { return A[x]; } int mid = x+(y-x)/2; int leftSum = 0; int rightSum = 0; int leftMaxValue = A[m-1]; int rightMaxValue = A[m]; int i; int maxValue=max(MaxSubseqSum3(a,x,m),MaxSubseqSum3(a,m,y)); for (i = mid - 1; i >= x; --i) { leftSum += A[i]; leftMaxValue = max(leftMaxValue,leftSum); } for (i = m; i < y; ++i) { rightSum += A[i]; rightMaxValue = max(rightMaxValue,rightSum); } return max(maxValue,leftMaxValue+rightMaxValue); } |
算法四:在线处理,达到理想的复杂度了,O(N)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int MaxSubseqSum4( int A[], int N) { int ThisSum,MaxSum; int i; ThisSum = MaxSum = 0; for (i = 0; i < N; ++i) { ThisSum += A[i]; //向右累加 if (ThisSum > MaxSum) { MaxSum = ThisSum; } else if (ThisSum < 0) { ThisSum = 0; } } return MaxSum; } |
=============================================
最后AC的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <cstdio> using namespace std; #define MAXN 100000 int main() { freopen ( "in.txt" , "r" ,stdin); int list[MAXN]; int n,i,; int ThisSum, MaxSum; int head,tail; scanf ( "%d" ,&n); int start = 0,end = n-1; for ( int i = 0; i < n; ++i) { scanf ( "%d" ,&list[i]); } ThisSum = MaxSum = 0; for ( int i = 0; i < n; ++i) { if (ThisSum >=0) { ThisSum += list[i]; tail = i; } else { ThisSum = list[i]; head = i; tail = i; } if (ThisSum > MaxSum ||(ThisSum == 0 && MaxSum == 0)) { MaxSum = ThisSum; start = head; end = tail; } } printf ( "%d %d %d\n" ,MaxSum, list[start], list[end]); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步