(leetcode题解)Maximum Subarray

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.

这是一道经典的题目,给定一个数组求和最大的子数组。算法导论对这道给出了两种解法,一种是分治策略,另一种是动态规划。

 

动态规划的解法是自底向上的方法,首先要找到题目的递推关系,这道题隐含了一个递推关系:pre=max(pre+nums[i],nums[i]),pre当前值下子数组和的最大值。

因而只要获取pre的最大值即可。C++实现如下。

int maxSubArray(vector<int>& nums) {
        int length=nums.size();
        int i=0;
        int max=nums[0];
        int pre=nums[0];
        i++;
        while(i<length)
        {
            if(pre+nums[i]>nums[i])
                pre=nums[i]+pre;
            else
                pre=nums[i];
            if(max<pre)
                max=pre;
            i++;
        }
        return max;
    }

分治策略是将问题的规模不断的缩小,但问题本质不变。

这道题采用二分法,最大子数组可以在下列三种情况获得:

1、最大值在[left,mid-1]

2、最大值在[mid+1,right]

3、最大值跨越mid,需要计算mid之前的最大值以及之后的最大值,然后三者之和就是最大值

C++实现如下:

int maxSubArray(vector<int>& nums) {
       return divide(nums,0,nums.size()-1,INT_MIN);
    }
    int divide(vector<int>& nums,int low,int high,int tmax)
    {
        if(low>high)
            return INT_MIN;
        int mid=(low+high)/2;
        int lmax=divide(nums,low,mid-1,tmax);
        int hmax=divide(nums,mid+1,high,tmax);
        tmax=max(lmax,tmax);
        tmax=max(hmax,tmax);
        int lnum=0;
        int ltemp=0;
        for(int i=mid-1;i>=low;i--)
        {
            lnum+=nums[i];
            if(lnum>ltemp)
                ltemp=lnum;
        }
        int hnum=0;
        int htemp=0;
        for(int i=mid+1;i<=high;i++)
        {
            hnum+=nums[i];
            if(hnum>htemp)
                htemp=hnum;
        }
        return max(tmax,(htemp+ltemp+nums[mid]));
    }
 
原文地址:https://www.cnblogs.com/kiplove/p/6994044.html