劍指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; } }
程式碼解析:
- 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