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 }; } }