题目:求连续子数组的最大和
要求:时间复杂度O(n)
算法思路:
基于动态规划的思想:
1、算法中维护两个最大和:全局最大和max、局部最大和sum
2、全局最大和的维护:当局部>全局时,更新全局,将其赋值为局部值
3、局部最大和的维护:若当前局部<0,则新的最大和将不包含前面累积的最大和(因为前面的累积 对于 得到最大和 起的是负作用),那么新的最大和将是下一个元素本身。若当前局部>=0,则新的最大和将包含前面累积的最大和(前面的累积起正作用),那么新的最大和将是旧最大和(即前面累积)+下一个元素
4、这里的思想就是:根据前面累积的和起正作用还是负作用,来判断是否要重新起一个新的子数组的头;而往前面的累积上加新元素应当加到何时停止,则是通过max与sum的比较来看的:如果sum大,说明新加的元素起到的是正作用,如果sum不如max大,说明新加的元素起到的是负作用。直到sum中加的一系列连续的新元素起到正作用的时候,才更新max,不然max就一直停留在之前那个最好的局部最优的值上
5、也就是说局部sum维护的是子数组的头要从哪里开始才能达到最优,而全局的max维护的是子数组的尾在哪里结束
6、另外:如果要求的不止是最大和,还要求子数组(也就是记录产生这个最大和的子数组的起止下标,那就还是基于局部和全局的思想,维护两对起止下标就可以了,只有sum>max导致max更新时,全局下标才跟着局部下标更新;局部下标则在另起新数组时更新为起止都是新元素下标,不另起时,每加一个元素就把尾端下标+1更新就可以了)
java代码实现:
1 | public class MaxSumSubset { |
main函数测试:
1 | public class Main { |