public class MaxSubArray
{
public static void main(String[] args)
{
int[] array = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
Result result = getMaxSubArrayNLogN(array, 0, array.length - 1);
System.out.println(result.leftIndex);
System.out.println(result.rightIndex);
System.out.println(result.sum);
Result result1 = getMaxSubArrayN(array);
System.out.println(result1.leftIndex);
System.out.println(result1.rightIndex);
System.out.println(result1.sum);
}
public static Result getMaxSubArrayNLogN(int[] array, int start, int end)
{
if(start == end)
{
Result result = new Result();
result.leftIndex = start;
result.rightIndex = end;
result.sum = array[start];
return result;
}
int middle = (end - start)/2 + start;
Result leftResult = getMaxSubArrayNLogN(array, start, middle);
Result middleResult = getMaxCrossSubArray(array, start, end);
Result rightResult = getMaxSubArrayNLogN(array, middle + 1, end);
if(leftResult.sum > middleResult.sum)
{
if(leftResult.sum > rightResult.sum)
{
return leftResult;
}
else
{
return rightResult;
}
}
else
{
if(middleResult.sum > rightResult.sum)
{
return middleResult;
}
else
{
return rightResult;
}
}
}
public static Result getMaxSubArrayN(int[] array)
{
Result result = new Result();
if(array.length == 1)
{
result.leftIndex = 0;
result.rightIndex = 0;
result.sum = array[0];
return result;
}
int leftIndex = 0;
int rightIndex = 0;
int maxSum = array[0];
for(int i = 1; i < array.length; i++)
{
if(array[i] <= 0)
{
continue;
}
int tmpMaxSum = Integer.MIN_VALUE;
int tmpSum = 0;
int tmpLeftIndex = 0;
for(int j = i; j > rightIndex; j--)
{
tmpSum += array[j];
if(tmpSum > tmpMaxSum)
{
tmpMaxSum = tmpSum;
tmpLeftIndex = j;
}
}
if(tmpSum < 0)
{
if(tmpMaxSum > maxSum)
{
leftIndex = tmpLeftIndex;
rightIndex = i;
maxSum = tmpMaxSum;
}
}
else
{
rightIndex = i;
maxSum += tmpSum;
}
}
result.leftIndex = leftIndex;
result.rightIndex = rightIndex;
result.sum = maxSum;
return result;
}
private static Result getMaxCrossSubArray(int[] array, int start, int end)
{
Result result = new Result();
int middle = (end - start)/2 + start;
int leftMaxNumber = Integer.MIN_VALUE;
int leftSum = 0;
int leftIndex = -1;
int i = middle;
while( i >= start)
{
leftSum += array[i];
if(leftSum > leftMaxNumber)
{
leftMaxNumber = leftSum;
leftIndex = i;
}
i--;
}
int rightMaxNumber = Integer.MIN_VALUE;
int rightSum = 0;
int rightIndex = -1;
i = middle + 1;
while( i <= end)
{
rightSum += array[i];
if(rightSum > rightMaxNumber)
{
rightMaxNumber = rightSum;
rightIndex = i;
}
i++;
}
result.leftIndex = leftIndex;
result.rightIndex = rightIndex;
result.sum = leftMaxNumber + rightMaxNumber;
return result;
}
private static class Result
{
int leftIndex;
int rightIndex;
int sum;
}
}