problem:

 

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.

 

Hide Tags
 Divide and Conquer Array Dynamic Programming
题意:找出一个序列的最大和连续子序列
 

 

thinking:

(1)这道题解法特别多:

方法1:将每个数和后一个数字相加,得到一个正负分布的序列,正数项对最大和子序列实用,作比較就可以

方法2:暴力匹配,两层循环,调用max()函数。时间复杂度O(n*n),也能够算出结果,可是提交超时

方法3:採用DP。时间复杂度O(n)

方法4:分治法。时间复杂度为nlog(n)

(2)本人实现了方法3 和方法4

 

code:

DP 法:

 

class Solution {
public:
    int maxSubArray(int A[], int n) {
        int sum=A[0];
        int maxsum=A[0];
        for(int i=1;i<n;i++)
        {
            if(sum<0)    //DP核心
                sum=0;
            sum+=A[i];
            maxsum=max(sum,maxsum);
        }
        return maxsum;
    }


};

分治法:

 

 

class Solution {
public:
    int maxSubArray(int A[], int n) {
        int ret=maxsub(A,0,n-1);
        return ret;

    }
protected:
    int maxsub(int A[], int start, int end)
    {
        int max_left=INT_MIN,max_mid=INT_MIN,max_right=INT_MIN;
        if(start==end)
            return A[start];
        if(start+1==end)
        {
            int a=max(A[start],A[end]);
            return a>(A[start]+A[end])?a:(A[start]+A[end]);
        }
        int mid=(start+end)/2;
        int tmp_sum=A[mid];
        max_mid=tmp_sum;
       
        int i=mid-1;
        int j=mid+1;
        while(i>=start)  //难点在于当连续最大和子序列分布在mid的一側或两側时,怎么处理
        {
            
            tmp_sum+=A[i];
            i--;
            max_mid=max(max_mid,tmp_sum);
            
        }
        if(max_mid>A[mid])  //推断是处于两側,还是处于一側
            tmp_sum=max_mid;
        else
            tmp_sum=A[mid];
        while(j<=end)
        {
            
            tmp_sum+=A[j];
            j++;
            max_mid=max(max_mid,tmp_sum);
            
        }
        
        max_left=max(max_left,maxsub(A,start,mid-1));//二分轮廓
        max_right=max(max_right,maxsub(A,mid+1,end));
        int tmp_max = max(max_left,max_right);
        return max_mid>tmp_max?max_mid:tmp_max;
    }


};