689. Maximum Sum of 3 Non-Overlapping Subarrays
T: O(n)
S: O(n)
class Solution {
public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
int n = nums.length;
int subSumLen = n - k + 1;
int[] subSum = new int[subSumLen];
int sum = 0;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
// find subarray_sum
subSum[0] = sum; // [0 1] 2
for (int i = k; i < n; i++) {
sum -= nums[i - k]; // sum -= nums[k - 2] -> nums[2-2] = nums[0]
sum += nums[i]; // sum += nums[i] = nums[k] = nums[2]
subSum[i - k + 1] = sum; // subSum[k-k+1] = sunSum[1]
}
// find max subarray sum from left, record index
int[] maxLeftIdx = new int[subSumLen];
for (int i = 1; i < subSumLen; i++) {
if (subSum[i] > subSum[maxLeftIdx[i-1]]) {
maxLeftIdx[i] = i;
} else {
maxLeftIdx[i] = maxLeftIdx[i-1];
}
}
// find max subarray sum from right, record index
int[] maxRight = new int[subSumLen];
maxRight[subSumLen-1] = subSumLen-1;
for (int i = subSumLen - 2; i >= 0; i--) {
if (subSum[i] >= subSum[maxRight[i+1]]) { // why here has a "="" , because return the lexicographically smallest one., so if there is equal sum but smaller index, we pick smaller index
maxRight[i] = i;
} else {
maxRight[i] = maxRight[i+1];
}
}
int[] result = new int[3];
int max = 0;
// find i-k(range), i, i+k (range) -> i-k, i+k is the (range)idx with maxSubSum
for (int i = k; i < subSumLen - k; i++) {
int threeSum = subSum[maxLeftIdx[i-k]] + subSum[i] + subSum[maxRight[i+k]];
if (threeSum > max) {
result = new int[]{maxLeftIdx[i-k], i, maxRight[i+k]};
max = threeSum;
}
}
return result;
}
}
/***
find three "non-overlapping" subarrays of length k with maximum sum
x x x starting point
0 1 2 3 4 5 6 7
[1,2,1,2,6,7,5,1]
x x x x x x
x. x. x
0 1 2 3 4 5 6 7 8
[1,2,1,2,1,2,1,2,1]
save sum for
n - k + 1 subarray with len k
[1,2,1,2,6,7,5,1]
[. ]
[ ]
[ ]
subsum
leftMax
rightMax
find max( subsum[leftMax[i]] + subsum[i] + subsum[rightMax[i]] )
and record that 3 index for ans
T: O(n)
S: O(n)
[1,2,1,2,1,2,1,2,1]
3 3 3 3 3 3 3 3
*/
Last updated
Was this helpful?