LeetCode-53 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.

分别给出O(n)时间复杂度和分治解法。
1. O(n)时间复杂度的方法属于动态规划的方法(这是网上的说法,不过楼主不太明白为什么是动态规划)。假设最大和的子串为A[i...j],其中0<i<k<j<n。则A[i,k]的和大于0,否则A[k+1, j]>A[i,j],与假设矛盾。这是该解法的主要思想。代码如下:

public int maxSubArray(int[] A) {
        int sum = 0;
        int maxSum = Integer.MIN_VALUE;
        
        for(int i=0; i<A.length; i++) {
            sum = sum + A[i];
            if(sum > maxSum)
                maxSum = sum;
            if(sum < 0) 
                sum = 0;
        }
        return maxSum;
    }

 

分治解法的思想是:A[0,n]的最大和子串有三种情况:

1. 在左半子串A[0,n/2];

2. 在右半子串A[n/2 + 1, n];

3. 一部分在左半子串,另一部分在右半子串A[i, j],0<i<n/2<j<n;

对于1,2,继续使用分治法缩小求解范围,由子问题求得原问题;对于3,只需遍历数组,求得以A[n/2]为中间一点的某个子串的和;

取3中情况中的最大值即为原问题的解。代码如下:

public int maxSubArrayDP(int[] A, int start, int over) {
        if(start >  over)
            return Integer.MIN_VALUE;
        if(start == over)
            return A[start];
        
        int mid = (start + over) / 2;
        int leftMax = maxSubArrayDP(A, start, mid);
        int rightMax = maxSubArrayDP(A, mid+1, over);
        
        int sum = 0;
        int leftMaxSum = Integer.MIN_VALUE;
        int rightMaxSum = Integer.MIN_VALUE;
        for(int i=mid; i>=0; i--) {
            sum += A[i];
            if(sum > leftMaxSum) {
                leftMaxSum = sum;
            }
        }
        sum = 0;
        for(int i=mid+1; i<=over; i++) {
            sum += A[i];
            if(sum > rightMaxSum) {
                rightMaxSum = sum;
            }
        }
        
        if(leftMax > rightMax) {
            return (leftMax > (leftMaxSum+rightMaxSum) ? leftMax : (leftMaxSum+rightMaxSum));
        } else {
            return (rightMax > (leftMaxSum+rightMaxSum) ? rightMax : (leftMaxSum+rightMaxSum)); 
        }
    }

 

posted on 2015-02-12 19:13  linxiong1991  阅读(109)  评论(0编辑  收藏  举报

导航