【练习题】——连续最大子数组问题(最简单的解释)

问题描述:

输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。

例:输入的数组为1, -2, 3, 10, -4, 7, 2, -5,
和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。

分析:

int maxSum(int* a, int n)
{
    int sum = 0; //当前子数组和
    int max = 0; //记录当前最大和的值

    for (int i = 0; i<n; ++i)
    {
        if (sum<0)          //当前子数组和小于0,为负数 
            sum = a[i];
        else                //当前和大于0
            sum += a[i];

        if (sum>max)        //当前和大于之前记录的最大和,对max进行更新
            max=sum;
    }
    return max;
}

这里写图片描述
我们的问题是要选出“和最大”的连续子数组:

  • 要点一:和最大;
  • 要点二:连续;

    所以我们选择的标准是和,我们可以遍历数组,逐个相加,当此时相加的和小于0时,(就可以对前面的值进行抛弃),我们就可以对这个我们的子数组进行更新,从下一个数从新进行记录,每次用和sum和记录的之前记录的max进行比较,当此时的和sum>max,对max的记录值进行更新。直到遍历完这个数组,就可以得到数组的最大子数组和。

具体:这里写图片描述
当sum的和为-1时,这是就可以对{1,-2}进行抛弃,因为无论后面与那些数进行组合,有这两个数必然会比没有这两个数和小


总结:设sum为包含第i个元素的连续子数组的和,max 当前记录的最大子数组的和。
对第i+1个元素有两种选择:

  1. 做为新子数组的第一个元素
  2. 放入前面找到的子数组

猜你喜欢

转载自blog.csdn.net/lindaxym/article/details/80481675