題目描述:給定一個數組,數組裏可能有正數,負數,0,數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個一個和。求所有子數組和的最大值。例如,如果輸入數組爲,和的最大子數組爲{1,-2,3,10,-4,7,2,-5},那麼輸出爲該子數組的和18
解法一:蠻力枚舉法(時間複雜度:O(N*N*N))
用三個for循環三層遍歷,求出數組中每一個子數組的和,最終求出這些子數組和中最大的一個值。
#include<iostream>
using namespace std;
int MaxSubArray(int array[], int n)
{
int maxSum = array[0]; //全是負數的情況,返回最大值
int curSum = 0;
for(int i=0; i<n; ++i)
{
for(int j=i; j<n; ++j)
{
for(int k=i; k<=j; ++k)
curSum += array[k];
if(curSum > maxSum)
maxSum = curSum;
//這裏要注意清零,否則計算的是所有子數組的和
curSum = 0;
}
}
return maxSum;
}
int main()
{
int array[] = {1,-2,3,10,-4,7,2,-5};
int ret1 = MaxSubArray(array, sizeof(array)/sizeof(array[0]));
cout<<ret1<<endl;
system("pause");
return 0;
}
解法二:動態規劃:從前往後只掃描一遍數組,時間複雜度爲O(n)
令curSum是以當前元素結尾的最大連續子數組的和,maxSum是全局的最大子數組的和,當往後掃描時,對第j個元素由兩種選擇,要麼放入前面的找到的子數組,要麼作爲一個新子數組的第一個元素:
如果curSum>0,則令curSum加上array[j];如果curSum<0,則curSum被置爲當前元素,即curSum = array[j];
int MaxSubArray2(int* array, int n)
{
int curSum = 0;
int maxSum = array[0]; //數組全爲負數的情況,返回最大數
for(int j=0; j<n; ++j)
{
if(curSum >= 0)
curSum += array[j];
else
curSum = array[j];
if(curSum > maxSum)
maxSum = curSum;
}
return maxSum;
}
int main()
{
int array[] = {1,-2,3,10,-4,7,2,-5};
int ret2 = MaxSubArray2(array, sizeof(array)/sizeof(array[0]));
cout<<ret2<<endl;
system("pause");
return 0;
}