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:
Divide and conquer
2. http://www.cnblogs.com/cheapcrook/archive/2013/01/27/2878580.html
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
Java:
1. http://joycelearning.blogspot.com/2013/10/leetcode-maximum-subarray.html
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;
}
}
Divide and conquer
// 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;
}
}
2. http://www.cnblogs.com/cheapcrook/archive/2013/01/27/2878580.html
Divide and conquer
public class Solution {
public int maxSum(int[] a, int left, int right){
if(left == right) return a[left];
int mid = (left + right) / 2;
int leftSum = maxSum(a, left, mid);
int rightSum = maxSum(a, mid+1, right);
int tmpLeftSum = 0;
int tmpRightSum = 0;
int s1 = Integer.MIN_VALUE, s2 = Integer.MIN_VALUE;
for(int i = mid; i >= left; i--){
tmpLeftSum += a[i];
s1 = Math.max(s1, tmpLeftSum);
}
for(int i = mid+1; i <= right; i++){
tmpRightSum += a[i];
s2 = Math.max(s2, tmpRightSum);
}
return Math.max(Math.max(leftSum, rightSum), s1+s2);
}
public int maxSum2(int[] A){
int len = A.length;
int ans = A[0];
int tmpSum = A[0];
for(int i = 1; i < len; i++){
if(tmpSum > 0){
tmpSum = tmpSum + A[i];
}
else tmpSum = A[i];
ans = Math.max(ans, tmpSum);
}
return ans;
}
public int maxSubArray(int[] A) {
// Start typing your Java solution below
// DO NOT write main() function
return maxSum(A, 0, A.length-1);
//return maxSum2(A);
}
}