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.

103 lines
2.5 KiB

2 years ago
package class22;
// 本题测试链接 : https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/
public class Code01_MaximumSumof3NonOverlappingSubarrays {
// public static int[] maxSumArray1(int[] arr) {
// int N = arr.length;
// int[] help = new int[N];
// // help[i] 子数组必须以i位置结尾的情况下累加和最大是多少
// help[0] = arr[0];
// for (int i = 1; i < N; i++) {
// int p1 = arr[i];
// int p2 = arr[i] + help[i - 1];
// help[i] = Math.max(p1, p2);
// }
// // dp[i] 在0~i范围上随意选一个子数组累加和最大是多少
// int[] dp = new int[N];
// dp[0] = help[0];
// for (int i = 1; i < N; i++) {
// int p1 = help[i];
// int p2 = dp[i - 1];
// dp[i] = Math.max(p1, p2);
// }
// return dp;
// }
//
// public static int maxSumLenK(int[] arr, int k) {
// int N = arr.length;
// // 子数组必须以i位置的数结尾长度一定要是K累加和最大是多少
// // help[0] help[k-2] ...
// int sum = 0;
// for (int i = 0; i < k - 1; i++) {
// sum += arr[i];
// }
// // 0...k-2 k-1 sum
// int[] help = new int[N];
// for (int i = k - 1; i < N; i++) {
// // 0..k-2
// // 01..k-1
// sum += arr[i];
// help[i] = sum;
// // i == k-1
// sum -= arr[i - k + 1];
// }
// // help[i] - > dp[i] 0-..i K
//
// }
public static int[] maxSumOfThreeSubarrays(int[] nums, int k) {
int N = nums.length;
int[] range = new int[N];
int[] left = new int[N];
int sum = 0;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
range[0] = sum;
left[k - 1] = 0;
int max = sum;
for (int i = k; i < N; i++) {
sum = sum - nums[i - k] + nums[i];
range[i - k + 1] = sum;
left[i] = left[i - 1];
if (sum > max) {
max = sum;
left[i] = i - k + 1;
}
}
sum = 0;
for (int i = N - 1; i >= N - k; i--) {
sum += nums[i];
}
max = sum;
int[] right = new int[N];
right[N - k] = N - k;
for (int i = N - k - 1; i >= 0; i--) {
sum = sum - nums[i + k] + nums[i];
right[i] = right[i + 1];
if (sum >= max) {
max = sum;
right[i] = i;
}
}
int a = 0;
int b = 0;
int c = 0;
max = 0;
for (int i = k; i < N - 2 * k + 1; i++) { // 中间一块的起始点 (0...k-1)选不了 i == N-1
int part1 = range[left[i - 1]];
int part2 = range[i];
int part3 = range[right[i + k]];
if (part1 + part2 + part3 > max) {
max = part1 + part2 + part3;
a = left[i - 1];
b = i;
c = right[i + k];
}
}
return new int[] { a, b, c };
}
}