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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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("测试结束");
}
}