首先,題目要求求出連續子序列的和的值爲最大的子序列,有點繞口,多讀幾遍就清楚了。一個序列有大量的連續子序列(排列組合問題了),要從衆多子序列中挑出和的值爲最大的那個序列。暴力解決的思路很簡單,直接遍歷所有的連續子序列並求它們的和,分別對比和的大小,取最大的值即可,時間複雜度爲n^2。
但是,算法之所以簡單,在於它的高效性。換個思路:我們其實並不需要求出每個連續子序列的和。有一個既定事實,那就是每一個連續子序列(以下簡稱子序列)都對應着一個 序列結尾位置,不同的子序列對應着一個 序列結尾位置。例如:
- 序列結尾位置的定義
有序列 {1, 3, -2, 4, -5},每一個逗號代表一個序列結尾位置,子序列{1,3,-2};{3,-2};{-2}均對應同一個結尾位置(第三個逗號),那麼以該位置結尾的子序列中,最大值顯然爲2。
- 問題轉化
原始序列中,一共有n-1個序列結尾位置,我們只需分別求出以n-1個位置結尾的最大子序列的值,再從n-1個最大子序列的值中求出最大值即爲原始序列的最大連續子序列和。
- 核心思想
回到例題,以第三個逗號結尾的最大子序列和怎麼求?當前處理到第i個數,即爲-2。有兩種情況,當前i-1個數的和sum大於0時,那麼前i個數的最大連續子序列和爲sum+a[i];當前i-1個數的和小於0時,前i個數的和爲a[i]。這就轉化成了0-1揹包的動態規劃問題。求前i+1個數的最大連續子序列和爲:
當sum+a[i]>0時:
sum+a[i]+a[i+1]
當sum+a[i]<0時:
a[i+1]
如此遞推狀態轉換方程就可以建立了。