一個整形數組,有正數有負數,求所有子數組的和的最大值。複雜度爲O(n)。
分析:
- 數組中有正數有負數。正數起正作用,負數起副作用。交叉起來亦可能最大子數組的中間包含一個負數,所以判斷每個的正負值無意義,需要判斷一個序列的和來判斷。
- 一個指針往前走,不斷加和。當和小於0時說明當前的子數組和爲負數,不管誰加上都副作用,可直接拋棄。不用擔心從這段中間某位置加起會不會好。我們原則是一負就拋棄,如果負數在前面馬上拋棄如[-1,-2,3]。如果能加了一段,說明負數偏後面[2,3,-2,-4]。則從當前位置前面都拋棄。
- 每次加和後,與當前最大值比較下。不斷刷新最大值。直至指針走到末尾結束。
代碼:
// offer-31-subarray.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
bool g_invalidinput = false;
int findmaxofsubarray(int * a, int length)
{
if(a == nullptr || length <= 0)
{
// 輸入非法返回0。標誌0是非法輸入的
g_invalidinput = true;
return 0;
}
g_invalidinput = false;
int cursum = 0;
int maxsum = 0x80000000; // int表示的最小值 -214...
for(int i = 0; i<length; ++i)
{
// 加到此處小於0,則重新開始加
if(cursum <= 0)
cursum = a[i];
// 否則一直向後加
else
cursum += a[i];
// 記錄最大值,一旦加的大了就刷新
if(cursum > maxsum)
maxsum = cursum;
}
return maxsum;
}
// test
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {1,-2,3,10,-4,7,2,-5};
cout << findmaxofsubarray(a, 8) << endl;
return 0;
}