連續子陣列最大和問題

2021-07-22 09:26:32 字數 2780 閱讀 2154

輸入乙個整形陣列,求陣列中連續的子陣列使其和最大。比如,陣列x

應該返回 x[2..6]的和187.

我們很自然地能想到窮舉的辦法,窮舉所有的子陣列的之和,找出最大值。

i, j的for迴圈表示x[i..j],k的for迴圈用來計算x[i..j]之和。

maxsofar = 0

for i = [0, n)

forj = [i, n)

sum = 0

for k = [i, j]

sum += x[k]

/* sum is sum of x[i..j] */

maxsofar = max(maxsofar, sum)

有三層迴圈,窮舉法的時間複雜度為o(

n3) o(n3)

我們注意到x[i..j]之和 = x[i..j-1]之和 + x[j],因此在j的for迴圈中,可直接求出sum。

maxsofar = 0

for i = [0, n)

sum = 0

for j = [i, n)

sum += x[j]

/* sum is sum of x[i..j] */

maxsofar = max(maxsofar, sum)

顯然,改進之後的時間複雜度變為o(

n2) o(n2)

。在計算fibonacci數時,應該還有印象:用乙個累加陣列(cumulative array)記錄前面n-1次之和,計算當前時只需加上n即可。同樣地,我們用累加陣列cumarr記錄:cumarr[i] = x[0] + . . . +x[i],那麼x [i.. j]之和 = cumarr[j] -cumarr[i - 1]

cumarr[-1] = 0

for i = [0, n)

cumarr[i] = cumarr[i-1] + x[i]

maxsofar = 0

for i = [0, n)

for j = [i, n)

sum = cumarr[j] - cumarr[i-1]

/* sum is sum of x[i..j] */

maxsofar = max(maxsofar, sum)

時間複雜度依然為o(

n2) o(n2)

。所謂分治法,是指將乙個問題分解為兩個子問題,然後分而解決之。具體步驟如下:

在計算m

c mc

時,注意:mc

mc必定包含總區間的中間元素,因此求mc

mc等價於從中間元素開始往左累加的最大值 + 從中間元素開始往右累加的最大值

float maxsum3(l, u)

if (l > u) /* zero elements */

return

0if (l == u) /* one element */

return

max(0, x[l])

m = (l + u) / 2

/* find max crossing to left */

lmax = sum = 0

for (i = m; i >= l; i--)

sum += x[i]

lmax = max(lmax, sum)

/* find max crossing to right */

rmax = sum = 0

for i = (m, u]

sum += x[i]

rmax = max(rmax, sum)

return

max(lmax+rmax,

maxsum3(l, m),

maxsum3(m+1, u));

容易證明,時間複雜度為o(

n∗lo

gn) o(n∗log n)

。kadane演算法又被稱為掃瞄法,該演算法用到了乙個啟發式規則:如果前面一段連續子陣列的和小於0,那麼就丟棄它。其實也蠻好理解的,舉個簡單例子,比如:陣列-1, 2, 3,-1為負數,為了使得子陣列之和最大,顯然不應當把-1計入進內。

max_ending_here記錄前面一段連續子陣列之和。

initialize:

max_so_far = 0

max_ending_here = 0

loop

foreach element of the array

(a) max_ending_here = max_ending_here + x[i]

(b) if(max_ending_here < 0)

max_ending_here = 0

(c) if(max_so_far < max_ending_here)

max_so_far = max_ending_here

return max_so_far

只遍歷了一遍陣列,因此時間複雜度為o(

n)o(n)

。[1] jon bentley, programming pearls.

[2] geeksforgeeks, largest sum contiguous subarray.

最大和連續子陣列

問題描述 乙個數值型陣列,其子陣列有多個,求其子陣列中最大的和值。所謂和值,是指數組所有元素相加的和。解法 1 掃瞄法,維護max變數,儲存最大和,其初始值為data 0 假設最大和子陣列的第一位下標為i,i從0到n 1,對於每個i值,從data i 開始,進行累加,每加乙個數,與max變數比較一次...

連續子陣列最大和

hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量的最大和為8 從第0個開始,到第...

連續子陣列最大和

求乙個陣列的連續的子陣列的最大和。例如 連續子向量的最大和為8 從第0個開始,到第3個為止 思路 對於每個元素,有兩種可能,一是加入到原來的子陣列成為新的一員 二是自己成為新子陣列的開頭,這兩種情況應該怎樣判斷呢 如果當前元素加入到子串行中,求和的結果比自己的值還小,那麼就自己成為新子串行的開頭 即...