剑指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

猜你喜欢

转载自blog.csdn.net/raylrnd/article/details/82620314