劍指offer 42 連續子陣列的最大和 題解

2021-10-08 08:16:58 字數 1457 閱讀 3801

輸入乙個整型陣列,陣列裡有整數也有負數。陣列中的乙個或連續多個整數組組成乙個子陣列。求所有子陣列和的最大值。要求時間複雜度為o(n)。

最容易想到的方法就是列舉陣列的所有子陣列並求出它們的和。乙個長度為n的陣列,總共有n(n+1)/2個子陣列。計算出所有子陣列的和,最快也要o(n2)的時間。不符合題意。

分析陣列規律可得:

1、從頭到尾逐個累加陣列中的每個數字,初始化和為0;(sum =0,greatsum=array[0])   

2、首先加上第乙個數字,從第二個數字開始累加,依次將累加和儲存到乙個臨時變數(sum)中;  

3、如果當前累加和(sum)小於0,那拋棄前面的子陣列和,從下乙個數字開始重新累加;相反,則將當前累加和(sum)與返回累加和(greatsum)進行比較,如果sum>greatsum,則更新greatsum。  

這樣比較進行一次遍歷之後,就可以得到最終的最大累加和,時間複雜度是o(n)。

下圖展示了計算陣列中子陣列的最大和的過程:

;//陣列中全為負數的情況

for(int i =

0;i)else

if(sum > greatsum)

}return greatsum;

}}在對greatsum變數進行初始化的時候,並沒有初始化為0,而是初始化為陣列的第乙個數字,是為了避免當陣列全為負數的情況。

除了上面的解法,我們還可以用動態規劃的思想來分析這個問題。如果用函式f(i)表示以第i個數字結尾的子陣列的最大和,那麼我們需要求出max[f(i)],其中0 <= i <= n。由狀態轉移方程a[j]=max(a[j],a[j-1]+a[j]),我們可以用如下遞迴公式求f(i):

f(i) = pdata[i] i = 0或者f(i-1) <= 0

f(i) = f(i-1) + pdata[i] i 不等於 0並且f(i-1) > 0

這個公式的意義:

當以第i-1個數字結尾的子陣列中所有數字的和小於0時,如果把這個負數與第i個數累加,則得到的結果比第i個數字本身還要小,所以這種情況下以第i個數字結尾的子陣列就是第i個數字本身。

如果以第i-1個數字結尾的子陣列中所有數字的和大於0,則與第i個數字累加就得到以第i個數字結尾的子陣列中所有數字的和。

雖然通常我們用遞迴的方式分析動態規劃的問題,但最終都會基於迴圈去編碼。

上述公式對應的**與前面給出的**類似。遞迴公式中的f(i)對應的變數是「累加子陣列和」sum,而max[f(i)]就是「最大子陣列和」greatsum。因此,可以說這兩種思路是異曲同工的。

[1] 《劍指offer(第二版)》 何海濤著

劍指offer42 連續子陣列的最大和

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

《劍指offer》 42 連續子陣列的最大和

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

劍指offer 42 連續子陣列的最大和

面試題42.連續子陣列的最大和 難度簡單42 輸入乙個整型陣列,陣列裡有正數也有負數。陣列中的乙個或連續多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o n 示例1 輸入 nums 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。...