(剑指Offer)面试题31:连续子数组的最大和
题目:
输入一个整型数组,数组里有正数也有负数,数组中一个或连续多个整数组成一个子数组,求所有子数组的和的最大值。要求时间复杂度为O(n)
思路:
1、数组累加
从头到尾逐个累加数组中的每个数字,当累加之和小于0时,从下一个元素开始累加,并通过一个变量保存最大和。
2、动态规划
思路与1一样,假设f(i)为以第i个数字结尾的子数组的最大和,那么
f(i)=A[i], f(i-1)<=0
f(i)=f(i-1)+A[i],f(i-1)>0
初始状态:f(0)=A[0]
最后求max(f(i)).
代码:
1、数字累加
#include <iostream> using namespace std; bool g_InvalidInput=false; int findGreatestSumOfSubArray(int *pData,int nLength){ if(pData==NULL || nLength<=0){ g_InvalidInput=true; return 0; } g_InvalidInput=false; int nCurSum=0; int nGreatestSum=0x80000000; for(int i=0;i<nLength;i++){ if(nCurSum<=0) nCurSum=pData[i]; else nCurSum+=pData[i]; if(nCurSum>nGreatestSum) nGreatestSum=nCurSum; } return nGreatestSum; } int main() { int A[]={1,-2,3,10,-4,7,2,-5}; int len=sizeof(A)/sizeof(A[0]); cout << findGreatestSumOfSubArray(A,len) << endl; return 0; }
2、动态规划
#include <iostream> using namespace std; bool g_InvalidInput=false; int findGreatestSumOfSubArray_DP(int *pData,int nLength){ if(pData==NULL || nLength<=0){ g_InvalidInput=true; return 0; } g_InvalidInput=false; int nCurSum[nLength]; int nGreatestSum=0x80000000; nCurSum[0]=pData[0]; for(int i=1;i<nLength;i++){ if(nCurSum[i-1]<=0) nCurSum[i]=pData[i]; else nCurSum[i]=nCurSum[i-1]+pData[i]; if(nCurSum[i]>nGreatestSum) nGreatestSum=nCurSum[i]; } return nGreatestSum; } int main() { int A[]={1,-2,3,10,-4,7,2,-5}; int len=sizeof(A)/sizeof(A[0]); cout << findGreatestSumOfSubArray_DP(A,len) << endl; return 0; }
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/459bd355da1549fa8a49e350bf3df484?rp=2
AC代码:
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { unsigned length=array.size(); if(length<=0) return 0; int curSum=0; int greatestSum=0x80000000; for(unsigned int i=0;i<length;i++){ if(curSum<=0) curSum=array[i]; else curSum+=array[i]; if(curSum>greatestSum) greatestSum=curSum; } return greatestSum; } };