Sponsored
Sponsored
This approach uses a prefix sum array to quickly calculate the sum of any subarray and a sliding window technique to explore possible starting points for the subarrays.
Time Complexity: O(n), since we make a constant number of passes through the array.
Space Complexity: O(n), due to the prefix, left, and right arrays.
1import java.util.Arrays;
2
3public class Main {
4 public static int[] maxSumOfThreeSubarrays(int[] nums, int k) {
5 int n = nums.length;
6 int[] prefix = new int[n + 1];
7 for (int i = 0; i < n; i++) {
8 prefix[i + 1] = prefix[i] + nums[i];
9 }
10 int[] left = new int[n];
11 int[] right = new int[n];
12 for (int i = k, total = prefix[k] - prefix[0]; i < n; i++) {
13 if (prefix[i + 1] - prefix[i + 1 - k] > total) {
14 left[i] = i + 1 - k;
15 total = prefix[i + 1] - prefix[i + 1 - k];
16 } else {
17 left[i] = left[i - 1];
18 }
19 }
20 for (int i = n - k - 1, total = prefix[n] - prefix[n - k]; i >= 0; i--) {
21 if (prefix[i + k] - prefix[i] >= total) {
22 right[i] = i;
23 total = prefix[i + k] - prefix[i];
24 } else {
25 right[i] = right[i + 1];
26 }
27 }
28 int[] result = new int[3];
29 int maxSum = 0;
30 for (int i = k; i <= n - 2 * k; ++i) {
31 int l = left[i - 1];
32 int r = right[i + k];
33 int totalSum = (prefix[i + k] - prefix[i]) + (prefix[l + k] - prefix[l]) + (prefix[r + k] - prefix[r]);
34 if (totalSum > maxSum) {
35 maxSum = totalSum;
36 result[0] = l;
37 result[1] = i;
38 result[2] = r;
39 }
40 }
41 return result;
42 }
43
44 public static void main(String[] args) {
45 int[] nums = {1, 2, 1, 2, 6, 7, 5, 1};
46 int k = 2;
47 System.out.println(Arrays.toString(maxSumOfThreeSubarrays(nums, k)));
48 }
49}
The Java solution uses a prefix sum array to quickly compute subarray sums. To identify the optimal subarrays, it employs two sliding window techniques (left
and right
) to track ideal starting indices for the leftmost and rightmost subarrays. The main loop determines the middle subarray and calculates the total possible sum.
This approach employs dynamic programming alongside a sliding window to optimize subarray sum calculations and ensure non-overlapping conditions.
Time Complexity: O(n), for traversal of the nums array multiple times.
Space Complexity: O(n), utilizing the dp, prefix, left, and right arrays.
1#include <vector>
using namespace std;
vector<int> maxSumOfThreeSubarraysDP(vector<int>& nums, int k) {
int n = nums.size();
vector<int> dp(n, 0);
vector<int> prefix(n + 1, 0);
vector<int> left(n), right(n);
for (int i = 0; i < n; ++i) {
prefix[i + 1] = prefix[i] + nums[i];
}
for (int i = 0; i < k; ++i) {
dp[i] = prefix[i + 1];
}
for (int i = k; i < n; ++i) {
if (prefix[i + 1] - prefix[i + 1 - k] >= dp[i - 1]) {
dp[i] = prefix[i + 1] - prefix[i + 1 - k];
left[i] = i + 1 - k;
} else {
dp[i] = dp[i - 1];
left[i] = left[i - 1];
}
}
right[n - k] = n - k;
for (int i = n - k - 1; i >= 0; --i) {
if (prefix[i + k] - prefix[i] >= prefix[right[i + 1] + k] - prefix[right[i + 1]]) {
right[i] = i;
} else {
right[i] = right[i + 1];
}
}
vector<int> result(3);
int maxSum = 0;
for (int i = k; i <= n - 2 * k; ++i) {
int l = left[i - 1];
int r = right[i + k];
int totalSum = (prefix[i + k] - prefix[i]) + (prefix[l + k] - prefix[l]) + (prefix[r + k] - prefix[r]);
if (totalSum > maxSum) {
maxSum = totalSum;
result = {l, i, r};
}
}
return result;
}
int main() {
vector<int> nums = {1, 2, 1, 2, 6, 7, 5, 1};
int k = 2;
vector<int> result = maxSumOfThreeSubarraysDP(nums, k);
for (int i : result) {
cout << i << " ";
}
return 0;
}
The C++ implementation uses dynamic programming to store the cumulative sums and utilizes left
and right
arrays to preserve optimal positions for subarray ranges. This allows efficiently choosing and maintaining the best sums for the problem's conditions.