|
| 1 | +package LeetCodeJava.Array; |
| 2 | + |
| 3 | +// https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/description/ |
| 4 | +/** |
| 5 | + * 1031. Maximum Sum of Two Non-Overlapping Subarrays |
| 6 | + * Medium |
| 7 | + * Topics |
| 8 | + * Companies |
| 9 | + * Hint |
| 10 | + * Given an integer array nums and two integers firstLen and secondLen, return the maximum sum of elements in two non-overlapping subarrays with lengths firstLen and secondLen. |
| 11 | + * |
| 12 | + * The array with length firstLen could occur before or after the array with length secondLen, but they have to be non-overlapping. |
| 13 | + * |
| 14 | + * A subarray is a contiguous part of an array. |
| 15 | + * |
| 16 | + * |
| 17 | + * |
| 18 | + * Example 1: |
| 19 | + * |
| 20 | + * Input: nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2 |
| 21 | + * Output: 20 |
| 22 | + * Explanation: One choice of subarrays is [9] with length 1, and [6,5] with length 2. |
| 23 | + * Example 2: |
| 24 | + * |
| 25 | + * Input: nums = [3,8,1,3,2,1,8,9,0], firstLen = 3, secondLen = 2 |
| 26 | + * Output: 29 |
| 27 | + * Explanation: One choice of subarrays is [3,8,1] with length 3, and [8,9] with length 2. |
| 28 | + * Example 3: |
| 29 | + * |
| 30 | + * Input: nums = [2,1,5,6,0,9,5,0,3,8], firstLen = 4, secondLen = 3 |
| 31 | + * Output: 31 |
| 32 | + * Explanation: One choice of subarrays is [5,6,0,9] with length 4, and [0,3,8] with length 3. |
| 33 | + * |
| 34 | + * |
| 35 | + * Constraints: |
| 36 | + * |
| 37 | + * 1 <= firstLen, secondLen <= 1000 |
| 38 | + * 2 <= firstLen + secondLen <= 1000 |
| 39 | + * firstLen + secondLen <= nums.length <= 1000 |
| 40 | + * 0 <= nums[i] <= 1000 |
| 41 | + * |
| 42 | + */ |
| 43 | +public class MaximumSumOfTwoNonOverlappingSubarrays { |
| 44 | + |
| 45 | + // V0 |
| 46 | +// public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) { |
| 47 | +// |
| 48 | +// } |
| 49 | + |
| 50 | + // V1 |
| 51 | + // IDEA: PREFIX SUM |
| 52 | + // https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/solutions/1489581/java-easy-to-understand-prefix-sum-by-rm-5d2z/ |
| 53 | + public int maxSumTwoNoOverlap_1(int[] A, int L, int M) { |
| 54 | + int sums[] = new int[A.length + 1]; |
| 55 | + |
| 56 | + for (int i = 1; i <= A.length; i++) |
| 57 | + sums[i] = A[i - 1] + sums[i - 1]; |
| 58 | + |
| 59 | + int maxLval = 0; |
| 60 | + int ans = 0; |
| 61 | + for (int i = L; i <= A.length - M; i++) { |
| 62 | + maxLval = Math.max(maxLval, sums[i] - sums[i - L]); |
| 63 | + ans = Math.max(ans, sums[i + M] - sums[i] + maxLval); |
| 64 | + } |
| 65 | + int maxRval = 0; |
| 66 | + for (int i = M; i <= A.length - L; i++) { |
| 67 | + maxRval = Math.max(maxRval, sums[i] - sums[i - M]); |
| 68 | + ans = Math.max(ans, sums[i + L] - sums[i] + maxRval); |
| 69 | + } |
| 70 | + return ans; |
| 71 | + } |
| 72 | + |
| 73 | + // V2 |
| 74 | + // IDEA: PREFIX SUM |
| 75 | + // https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/solutions/5171249/java-clean-solution-using-prefix-sum-det-lxok/ |
| 76 | + // Drive Function |
| 77 | + public int maxSumTwoNoOverlap_2(int[] nums, int firstLen, int secondLen) { |
| 78 | + int[] prefix = new int[nums.length + 1]; |
| 79 | + for (int i = 0; i < nums.length; i++) { |
| 80 | + prefix[i + 1] = prefix[i] + nums[i]; |
| 81 | + } |
| 82 | + |
| 83 | + return Math.max(solveHelper(prefix, firstLen, secondLen), |
| 84 | + solveHelper(prefix, secondLen, firstLen)); |
| 85 | + } |
| 86 | + |
| 87 | + private int solveHelper(int[] prefix, int len1, int len2) { |
| 88 | + int res = 0; |
| 89 | + int maxLength = Integer.MIN_VALUE; |
| 90 | + for (int i = len1 + len2; i < prefix.length; i++) { |
| 91 | + maxLength = Math.max(maxLength, |
| 92 | + prefix[i - len2] - prefix[i - len2 - len1]); |
| 93 | + res = Math.max(res, maxLength + prefix[i] - prefix[i - len2]); |
| 94 | + } |
| 95 | + return res; |
| 96 | + } |
| 97 | + |
| 98 | + // V3 |
| 99 | + // https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/solutions/913234/on-thought-process-java-by-133c7-wn3a/ |
| 100 | + public int maxSumTwoNoOverlap_3(int[] A, int L, int M) { |
| 101 | + int n = A.length; |
| 102 | + if (n == 0) { |
| 103 | + return 0; |
| 104 | + } |
| 105 | + if (L + M > n) { |
| 106 | + throw new IllegalArgumentException(); |
| 107 | + } |
| 108 | + |
| 109 | + int[] Ls = new int[n]; |
| 110 | + int[] Ms = new int[n]; |
| 111 | + |
| 112 | + int lSum = 0; |
| 113 | + int mSum = 0; |
| 114 | + |
| 115 | + for (int i = 0; i <= n - L; i++) { |
| 116 | + if (i == 0) { |
| 117 | + for (int j = 0; j < L; j++) { |
| 118 | + lSum += A[j]; |
| 119 | + } |
| 120 | + } else { |
| 121 | + lSum = lSum - A[i - 1] + A[i + L - 1]; |
| 122 | + } |
| 123 | + |
| 124 | + Ls[i] = lSum; |
| 125 | + } |
| 126 | + |
| 127 | + for (int i = 0; i <= n - M; i++) { |
| 128 | + if (i == 0) { |
| 129 | + for (int j = 0; j < M; j++) { |
| 130 | + mSum += A[j]; |
| 131 | + } |
| 132 | + } else { |
| 133 | + mSum = mSum - A[i - 1] + A[i + M - 1]; |
| 134 | + } |
| 135 | + |
| 136 | + Ms[i] = mSum; |
| 137 | + } |
| 138 | + |
| 139 | + int[] lmax = new int[n + 1]; |
| 140 | + int[] mmax = new int[n + 1]; |
| 141 | + |
| 142 | + for (int i = n - 1; i >= 0; i--) { |
| 143 | + lmax[i] = Math.max(lmax[i + 1], Ls[i]); |
| 144 | + mmax[i] = Math.max(mmax[i + 1], Ms[i]); |
| 145 | + } |
| 146 | + |
| 147 | + int ans = 0; |
| 148 | + for (int i = 0; i <= n - L - 1; i++) { |
| 149 | + ans = Math.max(ans, Ls[i] + mmax[i + L]); |
| 150 | + } |
| 151 | + for (int i = 0; i <= n - M - 1; i++) { |
| 152 | + ans = Math.max(ans, Ms[i] + lmax[i + M]); |
| 153 | + } |
| 154 | + |
| 155 | + return ans; |
| 156 | + } |
| 157 | + |
| 158 | + // V5 |
| 159 | + // https://leetcode.ca/2018-09-26-1031-Maximum-Sum-of-Two-Non-Overlapping-Subarrays/ |
| 160 | + public int maxSumTwoNoOverlap_5(int[] nums, int firstLen, int secondLen) { |
| 161 | + int n = nums.length; |
| 162 | + int[] s = new int[n + 1]; |
| 163 | + for (int i = 0; i < n; ++i) { |
| 164 | + s[i + 1] = s[i] + nums[i]; |
| 165 | + } |
| 166 | + int ans = 0; |
| 167 | + for (int i = firstLen, t = 0; i + secondLen - 1 < n; ++i) { |
| 168 | + t = Math.max(t, s[i] - s[i - firstLen]); |
| 169 | + ans = Math.max(ans, t + s[i + secondLen] - s[i]); |
| 170 | + } |
| 171 | + for (int i = secondLen, t = 0; i + firstLen - 1 < n; ++i) { |
| 172 | + t = Math.max(t, s[i] - s[i - secondLen]); |
| 173 | + ans = Math.max(ans, t + s[i + firstLen] - s[i]); |
| 174 | + } |
| 175 | + return ans; |
| 176 | + } |
| 177 | + |
| 178 | +} |
0 commit comments