Skip to the content.

Ex42 连续子数组的最大和

题目描述

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

解题思路

使用动态规划,得到如下公式: \(maxs(i)= \begin{cases} nums[i], & if\ i\ =\ 0\ or\ maxs[i-1]\ \le\ 0\\ nums[i]+maxs[i-1], & if\ i\ \ne\ 0\ and\ maxs[i-1]\ >\ 0 \end{cases}\) 另外,如果进一步优化的话,可以将max和上一个max保存下来,不再使用一个数组(vector)来保存。

代码

class Solution
{
public:
  int
  maxSubArray (std::vector<int> &nums)
  {
    int max = nums[0], prev = nums[0];
    for (std::vector<int>::size_type i = 1; i < nums.size (); ++i)
      {
        if (prev <= 0)
          {
            prev = nums[i];
            max = max > prev ? max : prev;
          }
        else
          {
            prev += nums[i];
            max = max > prev ? max : prev;
          }
      }
    return max;
  }
};

结果

执行结果:通过

执行用时:32 ms, 在所有 C++ 提交中击败了99.87%的用户

内存消耗:23 MB, 在所有 C++ 提交中击败了30.33%的用户

另一种解法

解题思路

这个想法比动态规划更复杂一些,有很多小的注意点,但是也比较直观。

代码

class Solution
{
public:
  int
  maxSubArray (std::vector<int> &nums)
  {
    int cur = nums[0], max = nums[0];
    for (int i = 1; i < nums.size (); ++i)
      {
        if (nums[i] >= 0)
          {
            if (cur < 0)
              {
                cur = nums[i];
              }
            else
              {
                cur += nums[i];
              }
            max = cur > max ? cur : max;
          }
        else if (nums[i] < 0 && -1 * nums[i] < cur)
          {
            max = cur > max ? cur : max;
            cur += nums[i];
          }
        else
          {
            max = cur > max ? cur : max;
            cur = nums[i];
          }
      }
    return cur > max ? cur : max;
  }
};

结果

执行结果:通过

执行用时:44 ms, 在所有 C++ 提交中击败了86.75%的用户

内存消耗:22.8 MB, 在所有 C++ 提交中击败了45.77%的用户