題目:
{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。給一個數組,返回它的最大連續子序列的和
解題思路
萬物皆可使用暴力法,暴力法還是比較容易的,O(n^2)的時間復雜度,我是滿足的,但是面試官顯然不滿足,使用動態規划可以是復雜度到O(n)。
博主看了幾篇關於最大連續子序列的和的博客,發現都是上來給出狀態方程:
max( dp[ i ] ) = getMax( max( dp[ i -1 ] ) + arr[ i ] ,arr[ i ] )
這誰頂的住啊,尤其是像博主這種算法能力很差的同學。
首先我們需要了解dp[i]到底是個啥,經過博主的不懈努力,終於發現dp[i]就是以數組下標為i的數做為結尾的最大子序列和,注意是以i為結尾,比如說現在有一個數組{6,-3,-2,7,-15,1,2,2},為了不搞,我們就下標以1開始,dp[3]就是以-2為結尾的,那么顯然dp[3]的最大值就是1咯(6,-3,-2),dp[4]要以7結尾那么以7結尾的子序列最大和就是8(6,-3,-2,7)。
知道dp[i]是啥后,現在我們開始細細品一下上面這個遞推式,求dp[i]的時候是不是有兩種可能,要么就是像上面的dp[4]一樣,dp[3]求出來是1了,再加上自己array[4]是最大的,那么還有一種可能就是說如果dp[3]我求出來是-100,那如果我也是dp[3]+array[4]的話是-93,這時候dp[3]反而是累贅,最大就是自己(因為前面定義了必須以i為結尾,也就說必須以7結尾)。
代碼實現
/**
* dp dp(i)=max(dp(i-1)+array[i],array[i])
* {6,-3,-2,7,-15,1,2,2},
* @author dingyu
*/
public class T29 {
public int FindGreatestSumOfSubArray(int[] array) {
//max就是上面的dp[i]
int max = array[0];
//因為這個dp[i]老是變,所以比如你dp[4]是8 dp[5]就變成-7了,所以需要res保存一下
int res = array[0];
for (int i = 1; i < array.length; i++) {
max = Math.max(max + array[i], array[i]);
res = Math.max(res, max);
}
return res;
}
}