689. Maximum Sum of 3 Non-Overlapping Subarrays
Problem Description
In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum.
Each subarray will be of size k, and we want to maximize the sum of all 3*k entries.
Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one. Here is the code:
Analysis and Solution
A direct thought is that we can calculate each interval’s sum and choose every possible combinations and pick the maximum one. However, the time complexity is not consistent. So we should use dp to simplify it.
For each point, we calculate the max left interval and the max right interval and record the position of intervals. Then we pick a maximum sum as the result.
class Solution {
public:
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
int n = nums.size();
vector<int> sums(n-k+1, 0);
for (int i=0; i<=n-k; i++) {
for (int j=i; j<i+k; j++) {
sums[i] += nums[j];
}
}
vector<int> priors(n, 0);
vector<int> posts(n, 0);
priors[k] = 0;
posts[n-2*k+1] = n-k+1;
for (int i=k+1; i <= n-2*k+1; i++)
priors[i] = sums[priors[i-1]] >= sums[i-k] ? priors[i-1] : i-k;
for (int i=n-2*k; i >= k; i--)
posts[i] = sums[posts[i+1]] > sums[i+k] ? posts[i+1] : i+k;
int s = 0;
vector<int> result;
for (int i=k; i <= n-2*k; i++) {
if (sums[i] + sums[priors[i]] + sums[posts[i]] > s) {
s = sums[i] + sums[priors[i]] + sums[posts[i]];
result = {priors[i], i, posts[i]};
}
}
return result;
}
};
However, this code costs about 700ms. Inspect it and in the first step the method to calculate the internal’s sum is too slow. A faster code is as below:
class Solution {
public:
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
int n = nums.size();
vector<int> sums(n+1, 0);
for (int i=1; i<=n; i++) {
sums[i] = sums[i-1] + nums[i-1];
}
for (int i=0; i<=n-k; i++) {
sums[i] = sums[i+k] - sums[i];
}
vector<int> priors(n, 0);
vector<int> posts(n, 0);
priors[k] = 0;
posts[n-2*k] = n-k;
for (int i=k+1; i <= n-2*k; i++)
priors[i] = sums[priors[i-1]] >= sums[i-k] ? priors[i-1] : i-k;
for (int i=n-2*k-1; i >= k; i--)
posts[i] = sums[posts[i+1]] > sums[i+k] ? posts[i+1] : i+k;
int s = 0;
vector<int> result;
for (int i=k; i <= n-2*k; i++) {
if (sums[i] + sums[priors[i]] + sums[posts[i]] > s) {
s = sums[i] + sums[priors[i]] + sums[posts[i]];
result = {priors[i], i, posts[i]};
}
}
return result;
}
};