You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.3 KiB

2 years ago
package class46;
import java.util.LinkedList;
// 给定一个数组arr和一个正数M
// 返回在子数组长度不大于M的情况下最大的子数组累加和
public class Code04_MaxSumLengthNoMore {
// O(N^2)的解法,暴力解,用作对数器
public static int test(int[] arr, int M) {
if (arr == null || arr.length == 0 || M < 1) {
return 0;
}
int N = arr.length;
int max = Integer.MIN_VALUE;
for (int L = 0; L < N; L++) {
int sum = 0;
for (int R = L; R < N; R++) {
if (R - L + 1 > M) {
break;
}
sum += arr[R];
max = Math.max(max, sum);
}
}
return max;
}
// O(N)的解法,最优解
public static int maxSum(int[] arr, int M) {
if (arr == null || arr.length == 0 || M < 1) {
return 0;
}
int N = arr.length;
int[] sum = new int[N];
sum[0] = arr[0];
for (int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
LinkedList<Integer> qmax = new LinkedList<>();
int i = 0;
int end = Math.min(N, M);
for (; i < end; i++) {
while (!qmax.isEmpty() && sum[qmax.peekLast()] <= sum[i]) {
qmax.pollLast();
}
qmax.add(i);
}
int max = sum[qmax.peekFirst()];
int L = 0;
for (; i < N; L++, i++) {
if (qmax.peekFirst() == L) {
qmax.pollFirst();
}
while (!qmax.isEmpty() && sum[qmax.peekLast()] <= sum[i]) {
qmax.pollLast();
}
qmax.add(i);
max = Math.max(max, sum[qmax.peekFirst()] - sum[L]);
}
for (; L < N - 1; L++) {
if (qmax.peekFirst() == L) {
qmax.pollFirst();
}
max = Math.max(max, sum[qmax.peekFirst()] - sum[L]);
}
return max;
}
// 用作测试
public static int[] randomArray(int len, int max) {
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = (int) (Math.random() * max) - (int) (Math.random() * max);
}
return arr;
}
// 用作测试
public static void main(String[] args) {
int maxN = 50;
int maxValue = 100;
int testTime = 1000000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int N = (int) (Math.random() * maxN);
int M = (int) (Math.random() * maxN);
int[] arr = randomArray(N, maxValue);
int ans1 = test(arr, M);
int ans2 = maxSum(arr, M);
if (ans1 != ans2) {
System.out.println(ans1);
System.out.println(ans2);
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}