|
|
package 第02期.mca_02;
|
|
|
|
|
|
// 每周有营养的大厂算法面试题
|
|
|
// 课时111~课时112
|
|
|
// 来自美团
|
|
|
// 最大子段和是
|
|
|
// 一个经典问题,即对于一个数组找出其和最大的子数组。
|
|
|
// 现在允许你在求解该问题之前翻转这个数組的连续一段
|
|
|
// 如翻转(1,2,3,4,5,6)的第三个到第五个元素組成的子数组得到的是(1,2,5,4,3,6),
|
|
|
// 则翻转后该数组的最大子段和最大能达到多少?
|
|
|
public class Code03_MaxSumOnReverseArray {
|
|
|
|
|
|
public static int maxSumReverse1(int[] arr) {
|
|
|
int ans = Integer.MIN_VALUE;
|
|
|
for (int L = 0; L < arr.length; L++) {
|
|
|
for (int R = L; R < arr.length; R++) {
|
|
|
reverse(arr, L, R);
|
|
|
ans = Math.max(ans, maxSum(arr));
|
|
|
reverse(arr, L, R);
|
|
|
}
|
|
|
}
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
public static void reverse(int[] arr, int L, int R) {
|
|
|
while (L < R) {
|
|
|
int tmp = arr[L];
|
|
|
arr[L++] = arr[R];
|
|
|
arr[R--] = tmp;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static int maxSum(int[] arr) {
|
|
|
int pre = arr[0];
|
|
|
int max = arr[0];
|
|
|
for (int i = 1; i < arr.length; i++) {
|
|
|
pre = Math.max(arr[i], arr[i] + pre);
|
|
|
max = Math.max(max, pre);
|
|
|
}
|
|
|
return max;
|
|
|
}
|
|
|
|
|
|
public static int maxSumReverse2(int[] arr) {
|
|
|
int n = arr.length;
|
|
|
int[] prefix = new int[n];
|
|
|
prefix[n - 1] = arr[n - 1];
|
|
|
for (int i = n - 2; i >= 0; i--) {
|
|
|
prefix[i] = arr[i] + Math.max(0, prefix[i + 1]);
|
|
|
}
|
|
|
int ans = prefix[0];
|
|
|
int suffix = arr[0];
|
|
|
int maxSuffix = suffix;
|
|
|
for (int i = 1; i < n; i++) {
|
|
|
ans = Math.max(ans, maxSuffix + prefix[i]);
|
|
|
suffix = arr[i] + Math.max(0, suffix);
|
|
|
maxSuffix = Math.max(maxSuffix, suffix);
|
|
|
}
|
|
|
ans = Math.max(ans, maxSuffix);
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
// 为了测试
|
|
|
public static int[] randomArray(int n, int v) {
|
|
|
int[] arr = new int[n];
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
arr[i] = (int) (Math.random() * v) - (int) (Math.random() * v);
|
|
|
}
|
|
|
return arr;
|
|
|
}
|
|
|
|
|
|
// 为了测试
|
|
|
public static void main(String[] args) {
|
|
|
int len = 50;
|
|
|
int value = 20;
|
|
|
int testTime = 20000;
|
|
|
System.out.println("测试开始");
|
|
|
for (int i = 0; i < testTime; i++) {
|
|
|
int n = (int) (Math.random() * len) + 1;
|
|
|
int[] arr = randomArray(n, value);
|
|
|
int ans1 = maxSumReverse1(arr);
|
|
|
int ans2 = maxSumReverse2(arr);
|
|
|
if (ans1 != ans2) {
|
|
|
System.out.println("出错了!");
|
|
|
for (int num : arr) {
|
|
|
System.out.print(num + " ");
|
|
|
}
|
|
|
System.out.println();
|
|
|
System.out.println(ans1);
|
|
|
System.out.println(ans2);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
System.out.println("测试结束");
|
|
|
}
|
|
|
|
|
|
}
|