53. Maximum Subarray (Array; DP)

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.

More practice:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

法I:动态规划。max_local存储到i之前的sum,如果<0,表示之前的sum对之后只可能有负贡献,所以忽略,直接考虑nums[i]。max_global存储目前为止出现过的最大sum。

动态转移方程是:

局部最优:max_local= max(max_local+nums[i], nums[i])

全局最优:max_global= max(max_global, max_local)

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int max_local = nums[0];  //maxSum may be negative, so can't simply write int curSum = 0
        int max_global = nums[0];
        for(int i = 1; i < nums.size(); i++){
            max_local = max(max_local+nums[i],nums[i]);
            max_global = max(max_global, max_local);
        }
        return max_global;
    }
};

法II:分治法

将数组分为左右两段,分别找到最大子串和,然后还要从中间开始往两边扫描,求出最大和,比较三个和取最大值。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return binarySearch(nums,0,nums.size()-1);
    }
    
    int binarySearch(vector<int>& nums, int left, int right){
        //right=left<=1的两种情况都要讨论
        if(left==right)
            return nums[left];
        if(right-left == 1){
            return max(max(nums[left],nums[right]),nums[left]+nums[right]);
        }
        
        int mid = left +((right-left)>>1);
        int leftmax = binarySearch(nums, left, mid);
        int rightmax = binarySearch(nums, mid+1, right);
        
        int curLeft = nums[mid],curRight=nums[mid+1], maxLeft=nums[mid], maxRight=nums[mid+1];
        for(int i = mid-1; i>=left; i--){
            curLeft+=nums[i];
            maxLeft = max(curLeft,maxLeft);
        }
        for(int i = mid+2; i <= right; i++){
            curRight+=nums[i];
            maxRight = max(curRight,maxRight);
        }
        
        return max(max(leftmax,rightmax),maxLeft+maxRight);
    }
};
原文地址:https://www.cnblogs.com/qionglouyuyu/p/4857251.html