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
.
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. Solution #1, O(n)
Just simply loop from left to right and return the max val.
2. Solution #2, Divide and conquer, O(n) also?
The max range can be in the left half, or in the right half, or across the mid of the array, so we just divide it to tree parts and recursive until we get the max value of each part, and then get the largest value.
Thanks to : http://fisherlei.blogspot.com/2012/12/leetcode-maximum-subarray.html
1. Solution #1, O(n)
Just simply loop from left to right and return the max val.
// O(n) public class Solution { public int maxSubArray(int[] A) { int sum = 0; int maxSum = Integer.MIN_VALUE; for(int i = 0; i < A.length; i++) { sum += A[i]; maxSum = Math.max(maxSum, sum); // re-set sum when < 0 (no need to keep neg value) if(sum < 0) sum = 0; } return maxSum; } }
2. Solution #2, Divide and conquer, O(n) also?
The max range can be in the left half, or in the right half, or across the mid of the array, so we just divide it to tree parts and recursive until we get the max value of each part, and then get the largest value.
// Devide and Conquer public class Solution { public int maxSubArray(int[] A) { int maxSum = Integer.MIN_VALUE; return findMaxSub(A, 0, A.length - 1, maxSum); } // recursive to find max sum // may appear on the left or right part, or across mid(from left to right) public int findMaxSub(int[] A, int left, int right, int maxSum) { if(left > right) return Integer.MIN_VALUE; // get max sub sum from both left and right cases int mid = (left + right) / 2; int leftMax = findMaxSub(A, left, mid - 1, maxSum); int rightMax = findMaxSub(A, mid + 1, right, maxSum); maxSum = Math.max(maxSum, Math.max(leftMax, rightMax)); // get max sum of this range (case: across mid) // so need to expend to both left and right using mid as center // mid -> left int sum = 0, midLeftMax = 0; for(int i = mid - 1; i >= left; i--) { sum += A[i]; if(sum > midLeftMax) midLeftMax = sum; } // mid -> right int midRightMax = 0; sum = 0; for(int i = mid + 1; i <= right; i++) { sum += A[i]; if(sum > midRightMax) midRightMax = sum; } // get the max value from the left, right and across mid maxSum = Math.max(maxSum, midLeftMax + midRightMax + A[mid]); return maxSum; } }
Thanks to : http://fisherlei.blogspot.com/2012/12/leetcode-maximum-subarray.html
No comments:
Post a Comment