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.linear time method.
2.
public class Solution {
public int maxSubArray(int[] A) {
int len = A.length;
int curr = A[0], next = A[0];
for(int i = 1; i < len; ++i){
next = (next <= 0) ? A[i] : next + A[i];
curr = Math.max(curr, next);
}
return curr;
}
}
divide and conquer method.
public class Solution {
/**
* This program is an implementation of divide-and-conquer method
* @param A --an array of integer
* @return the maximum sum of a subarray
* @author Averill Zheng
* @version 2014-06-04
* @since JDK 1.7
*/
public int maxSubArray(int[] A) {
return maxSubArrayHelper(A, 0, A.length);
}
/**
* The function is used to find the maximum sum of a contiguous subarray between index i (inclusive) and j
* (exclusive).
* @param A --an integer array.
* @param i --start index which is included.
* @param j --end index which is exclusive.
* @return int --maximum sum of a contiguous subarray.
*/
private int maxSubArrayHelper(int[] A, int i, int j){
int max = Integer.MIN_VALUE;
if(j > i){
if(j == i + 1)
max = A[i];
else{
int mid = i + (j - i) / 2;
int leftMax = maxSubArrayHelper(A, i, mid);
int rightMax = maxSubArrayHelper(A,mid, j);
int crossMax = crossMax(A, i, j, mid);
max = Math.max(Math.max(leftMax, crossMax), rightMax);
}
}
return max;
}
private int crossMax(int[] A, int i, int j, int mid){
//[i,mid) is the first half and [mid, j) is the second half
//both of them contains at least one element
//left max
int leftMax = A[mid - 1];
int leftSum = A[mid - 1];
for(int k = mid - 2; k > i - 1; --k){
leftSum += A[k];
leftMax = (leftMax < leftSum) ? leftSum : leftMax;
}
//right max
int rightMax = A[mid];
int rightSum = A[mid];
for(int k = mid + 1; k < j; ++k){
rightSum += A[k];
rightMax = (rightMax < rightSum) ? rightSum : rightMax;
}
return leftMax + rightMax;
}
}