53. Maximum Subarray

来源:互联网 发布:寂寞聊天软件 编辑:程序博客网 时间:2024/05/16 05:55
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.


这是一道典型动态规划问题。其核心在于找到子问题(So when it comes to DP, the first thing for us to figure out is the format of the sub problem(or the state of each sub problem). The format of the sub problem can be helpful when we are trying to come up with the recursive relation.)

我们从第一个元素开始向后退,在第i个元素时,想要求的是必须包含这个元素且这个元素作为最后一个元素的子数组的最大值maxSubArray(int A[], int i),并且已经解得必须包含其之前一个元素的子数组的最大值maxSubArray(int A[], int i-1),那么maxSubArray(A, i) = maxSubArray(A, i - 1) > 0 ? maxSubArray(A, i - 1) : 0 + A[i]; 再用maxSubArray(A, i)和之前的max进行比较,较大者就是新的max。

public int maxSubArray(int[] A) {        int n = A.length;        int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];        dp[0] = A[0];        int max = dp[0];                for(int i = 1; i < n; i++){            dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);            max = Math.max(max, dp[i]);        }                return max;}


分而治之算法:

Step1. Select the middle element of the array.
So the maximum subarray may contain that middle element or not.

Step 2.1 If the maximum subarray does not contain the middle element, then we can apply the same algorithm to the the subarray to the left of the middle element and the subarray to the right of the middle element.

Step 2.2 If the maximum subarray does contain the middle element, then the result will be simply the maximum suffix subarray of the left subarray plus the maximum prefix subarray of the right subarray

Step 3 return the maximum of those three answer.

class Solution {public:    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.        if(n==0) return 0;        return maxSubArrayHelperFunction(A,0,n-1);    }        int maxSubArrayHelperFunction(int A[], int left, int right) {        if(right == left) return A[left];        int middle = (left+right)/2;        int leftans = maxSubArrayHelperFunction(A, left, middle);        int rightans = maxSubArrayHelperFunction(A, middle+1, right);        int leftmax = A[middle];        int rightmax = A[middle+1];        int temp = 0;        for(int i=middle;i>=left;i--) {            temp += A[i];            if(temp > leftmax) leftmax = temp;        }        temp = 0;        for(int i=middle+1;i<=right;i++) {            temp += A[i];            if(temp > rightmax) rightmax = temp;        }        return max(max(leftans, rightans),leftmax+rightmax);    }};


原创粉丝点击