连续子数组的最大和(基于动态规划)

题目

  输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18。

思路

一般解法

  1. 从头到尾累加数字,保存到一个临时变量curr_sum中
  2. 如果前几项的和为负,则加上此和之后比本身的值还要小,抛弃原来所计算得到的和,curr_sum从本元素开始计数 ;否则,把当前元素累加到curr_sum
  3. 把curr_sum与最大值max_sum比较(max_sum保存每个连续数组的最大和)

class Solution {
public:
    int maxSubArray(vector<int> arr) {
        if (arr.size() == 0) {
            return 0;
        }            
        else if (arr.size() == 1) {
            return arr[0];
        }

        int curSum = 0;
        int maxSum = INT_MIN;
        for(int i = 0; i <arr.size(); ++i)
        {            
            if (curSum <= 0) {//如果前几项的和为负,则加上此和之后比本身的值还要小,数组从本元素开始计数
                curSum = arr[i];
            }
            else {
                curSum += arr[i];
            }
            maxSum = max(maxSum, curSum);                         
        }
        return maxSum;
    }
};

 动态规划

  f(i)表示以第i个数字结尾的子数组的最大和,那么只需求出max[f(i)],状态转移方程如下

      v[i],i==0||f(i-1)<0
f(i)=
      v[i]+f(i-1),i>0&&f(i-1)>0

code:

class Solution {
public:
    int maxSubArray(vector<int> arr) {
        if (arr.size()==0) {
            return 0;
        }            
        else if (arr.size()==1) {
            return arr[0];
        }            

        int curSum = 0;
        int maxSum = INT_MIN;
        for(int i = 0; i < arr.size(); ++i)
        {
            curSum = curSum < 0 ? arr[i] : arr[i]+curSum;
            maxSum = max(maxSum, curSum);
        }
        return maxSum;
    }
};

 

posted on 2019-01-08 12:16  tianzeng  阅读(498)  评论(0)    收藏  举报

导航