此處介紹四種方法,複雜度in descending order
一、o(n^3)
普通做法;
即在陣列中,遍歷起始和終止位置,然後從起始到終止位置累加求和,求得的sum與最大值比較,如果比最大值大,就賦值;
int best = 0;//ans
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
二、o(n^2)
用字首和,從起始到終止的求和過程所求得的sum,即為終止的字首和減去(起始位置-1)的字首和所得的值;
那麼在開始遍歷前,我們只要先求出字首和,然後再遍歷,用字首和來減就可以;
s[0] = 0;
for(int i = 1; i <= n; i++)
s[i] = s[i-1] + a[i];
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
maxs = max(maxs, s[j] - s[i-1]);
三、o(nlogn)
分治的思想,找到左一半的最大連續和和右一半的最大連續和,然後歸併;
int maxm(int *a, int x, int y)
對於分治時間複雜度的計算
t(n) = 2t(n/2) + n;
…… = 2(2t(n/4) + n/2) +n;
…… = 4t(n/4) + 2n;
…… = 4(2*(t(n/8) + n/4) + 2n;
…… = 8t(n/8) + 3n;
…… = 2^kt(n/2的k次方) + kn;//直到2^k== n;此時k = log(2,n);
…… = nt(1) + nlog(2,n);
…… = nlogn + n;
四、o(n)
第四種方法是在第二種方法的基礎上加以改進,實際上我們求最大連續子段和,就是求最大的s[j] - s[i-1],那麼當j確定時,要使s[j] - s[i - 1]最大,那麼s[i-1]應該最小,只要遍歷字首和陣列維護最小的s就可以;
s[0] = 0;
for(int i = 1; i <= n; i++)
s[i] = s[i-1] + a[i];
int mins = 0;
for(int i = 1; i <= n; i++)
最大連續和
這個問題對我來說還挺難的,當初做dp時水過去了,但沒徹底理解,這次打算好好分析一下,爭取徹底搞懂。首先,像 1 1 2 2 3 3 4 4 5 5這樣的數列,想要找連續最大和,可以有很多種方法,從最慢的列舉o n 3 到最快的動態規劃o n 毫無疑問,我們要選擇複雜度低的演算法。所以我這裡就只分析兩...
最大連續和
求陣列中數的最大連續和,如 1,1,1,1,1 最大連續和為3 一 動態規劃 當我們從頭到尾遍歷這個陣列的時候,對於陣列裡的乙個整數,它有幾種選擇呢?它只有兩種選擇 1 加入之前的subarray 2.自己另起乙個subarray。那什麼時候會出現這兩種情況呢?設狀態為f j 表示以s j 結尾的最...
最大連續和
給出乙個長度為n的序列a1,a2,an,求最大連續和 使用列舉 時間複雜度o n 3 best a 1 初始最大值 for int i 1 i n i 設si a1 a2 ai,則ai ai 1 aj sj si 1 連續子串行的和等於兩個字首之差 時間複雜度o n 2 s 0 0 for int ...