分治法求解。最大值必然出现在完全位于数组左边、完全位于数组右边,跨越中点三种情况。
package chapter4;
import java.util.Scanner;
/*
* 所有连续子数组中和最大的值
*/
public class FindMaximumSub {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//数组元素个数
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
long max = findMaxSub(arr, 0, arr.length - 1);
System.out.println(max);
}
private static Long findMaxSub(int[] arr, int i, int j) {
if (i == j) {
return (long) arr[i];
} else {
int mid = (int) Math.floor((i + j) / 2);
Long leftSum = findMaxSub(arr, i, mid);
Long rightSum = findMaxSub(arr, mid + 1, j);
Long crossSum = findMaxCrossSub(arr, i, j, mid);
if (leftSum >= rightSum && leftSum >= crossSum) {
return leftSum;
} else if (rightSum >= leftSum && rightSum >= crossSum) {
return rightSum;
} else {
return crossSum;
}
}
}
private static Long findMaxCrossSub(int[] arr, int i, int j, int mid) {
Long leftSum = (long) Integer.MIN_VALUE;
Long sum1 = 0l;
for (int k = mid; k >= i; k--) {
sum1 += arr[k];
if (sum1 > leftSum) {
leftSum = sum1;
int maxLeft = k;
}
}
Long rightSum = (long) Integer.MIN_VALUE;
Long sum2 = 0l;
for (int k = mid + 1; k <= j; k++) {
sum2 += arr[k];
if (sum2 > rightSum) {
rightSum = sum2;
int maxRight = k;
}
}
return rightSum + leftSum;
}
}
输入:4
1 4 -2 3
输出:6