[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.

click to show more practice.

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.

 解题思路:

1. 首先是简单的dp。

2. 对于分治,考虑将数组分为左右两段,则最大连续子序列和可能在左半段,也可能在右半段,还可能跨界。三种情况求最大就可以了。

class Solution {
public:
    int dpSolution(int *a, int n)
    {
        if(n == 0) return 0;
        int *dp = new int[n + 1];
        dp[0] = a[0];
        int m = dp[0];
        for(int i = 1;i < n;i++)
        {
            if(dp[i - 1] > 0) dp[i] = dp[i - 1] + a[i];
            else dp[i] = a[i];
            m = max(dp[i], m);
        }
        return m;
    }
    
    int *data;
    int divideConquerSolution(int *a, int n)
    {
        if(n == 0)
            return 0;
        data = a;
        return dcs(0, n);
    }
    
    int dcs(int a, int b)
    {
        if(b - a == 1)
            return data[a];
    
        int mid = (a + b) / 2;
        int left = dcs(a, mid), right = dcs(mid, b);
        int rightSum = 0, leftSum = 0, rightMax = -(1 << 30), leftMax = -(1 << 30);
        for(int i = mid; i < b;i++)
        {
            rightSum += data[i];
            rightMax = max(rightSum, rightMax);
        }
        for(int i = mid - 1; i >= a;i--)
        {
            leftSum += data[i];
            leftMax = max(leftSum, leftMax);
        }
        return max(max(left, right), leftMax + rightMax);
    }
    
    int maxSubArray(int A[], int n) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
       // return dpSolution(A, n);
       return divideConquerSolution(A, n);
    }
};
原文地址:https://www.cnblogs.com/changchengxiao/p/3416555.html