1. 程式人生 > >劍指offer:動態規劃---求最大連續子序列的和

劍指offer:動態規劃---求最大連續子序列的和

問題描述:給一個數組,返回它的最大連續子序列的和

例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。

演算法思想:當全為正數的時候,問題很好解決。但是,如果陣列中包含負數,是否應該向後擴充套件某個負數,並期望負數後面的正數會彌補它。

採用遞推思想:

F(i):以array[i]為末尾元素的子陣列的和的最大值,子陣列的元素的相對位置不變

F(i)=max(F(i-1)+array[i] , array[i])

res:所有子陣列的和的最大值

res=max(res,F(i))

如陣列[6, -3, -2, 7, -15, 1, 2, 2]

初始狀態:

    F(0)=6

    res=6

i=1:

    F(1)=max(F(0)-3,-3)=max(6-3,3)=3

    res=max(F(1),res)=max(3,6)=6

i=2:

    F(2)=max(F(1)-2,-2)=max(3-2,-2)=1

    res=max(F(2),res)=max(1,6)=6

i=3:

    F(3)=max(F(2)+7,7)=max(1+7,7)=8

    res=max(F(2),res)=max(8,6)=8

i=4:

    F(4)=max(F(3)-15,-15)=max(8-15,-15)=-7

    res=max(F(4),res)=max(-7,8)=8

以此類推

最終res的值為8

public class Solution {
public  int FindGreatestSumOfSubArray(int[] array) {
        int res = array[0]; //記錄當前所有子陣列的和的最大值
        int max=array[0];   //包含array[i]的連續陣列最大值
        for (int i = 1; i < array.length; i++) {
            max=Math.max(max+array[i], array[i]);//此時max期望後面的數(正數)會彌補它,剪左枝
            res=Math.max(max, res);//剪右枝
        }
        return res;
    }
}

程式碼解析:

  1. res=Math.max(max, res);//剪右枝,越往後max反而越小,則捨棄後面的max。

目的是找出max1,max2,max3..,maxi 中的最大值,採用打擂臺演算法。

      2.max=Math.max(max+array[i], array[i]);//此時max期望後面的數(正數)會彌補它,剪左枝

      若max+array[i] < array[i],則捨棄前面的節點,把當前節點設為max。考慮下面的情況:

      如陣列a[-1,-2,-3,-4,5,6]

      當i=5時,此時max由原來的負數替換成5