Pnig0s1992 p.s:比较直白简单的嵌套for循环顺序累加判断的方式就不介绍了,比较容易实现,而且时间复杂度O(N^3) or O(N^2)比较坑爹。这里用分治递归的方法去解决O(NlogN),当然还有动态规划的方法O(N)以后再说。
先简单总结下分治递归的基本过程:
1,传入待处理的序列集合,及初始下标(iLeft)和终点下标(iRight=N-1,N为元素个数)
2,处理小容量问题 e.g:if(iLeft == iRight){....}
3,将数据从中间分成两部分并将前后两部分依次递归调用。
4,处理每个子段的过程。
核心部分注释的比较详细了,纯算法练习,高手飘过。
- //Code By Pnig0s1992
- //Date:2012,3,12
- #include <stdio.h>
- #include <Windows.h>
- #include <stdlib.h>
- #define N 8
- int CallSubsequenceSum(int s[],int iLength);
- int SubsequenceSum(int s[],int iLeft,int iRight);
- int Maxinthree(int a,int b,int c);
- int main(int argc,CHAR * argv[])
- {
- int myList[N] = {4,-3,5,-2,-1,2,6,-2};
- int myResult;
- for(int i=0;i<N;i++)
- {
- printf("%d ",myList[i]);
- }
- myResult = CallSubsequenceSum(myList,N-1);
- printf("\n最大子序列和为:%d",myResult);
- system("pause");
- }
- int CallSubsequenceSum(int s[],int iLength)
- {
- return SubsequenceSum(s,0,iLength);
- }
- int SubsequenceSum(int s[],int iLeft,int iRight)
- {
- int iMaxLeftSum,iMaxRightSum; //表示
- int iRightBorderSum = 0,iLeftBorderSum = 0;
- int iMaxLeftBorderSum = 0,iMaxRightBorderSum = 0;
- int iCenter;
- if(iLeft == iRight) //解决小容量情况,当序列只有一个元素时,非负则返回唯一值,否则返回0(基准情况)
- {
- if(s[iLeft]>0)
- {
- return s[iLeft];
- }else
- {
- return 0;
- }
- }
- iCenter = (iLeft+iRight)/2;
- iMaxLeftSum = SubsequenceSum(s,iLeft,iCenter); //每次递归返回时,该值为该子段的最终左最大子序列和
- iMaxRightSum = SubsequenceSum(s,iCenter+1,iRight); //每次递归返回时,该值为该子段的右最大自序列和
- for(int i=iCenter;i>=iLeft;i--) //从中间向左扩展求子段的最大子序列和,必然包括子段的最右端数
- {
- iLeftBorderSum+=s[i];
- if(iLeftBorderSum>iMaxLeftBorderSum)
- {
- iMaxLeftBorderSum = iLeftBorderSum; //包含左端数的最大子序列和
- }
- }
- for(int j=iCenter+1;j<=iRight;j++) //从中间向右扩展求子段的最大子序列和,必然包括子段的最左端数
- {
- iRightBorderSum += s[j];
- if(iRightBorderSum > iMaxRightBorderSum)
- {
- iMaxRightBorderSum = iRightBorderSum; //包含右端数的最大子序列和
- }
- }
- //返回左子最大序列和,右最大子序列,及横跨中间的最大子序列和三者的最大值
- return Maxinthree(iMaxLeftSum,iMaxRightSum,iMaxLeftBorderSum+iMaxRightBorderSum);
- }
- int Maxinthree(int a,int b,int c)
- {
- if(b>a)
- a=b;
- if(a<c)
- return c;
- else
- return a;
- }
本文转hackfreer51CTO博客,原文链接:http://blog.51cto.com/pnig0s1992/803907,如需转载请自行联系原作者