Maximum Sum of 3 Non-Overlapping Subarrays

hard dp prefix sum

Problem

Find indices of 3 non-overlapping length-k subarrays with maximum total sum (lex-smallest indices on ties).

Inputnums=[1,2,1,2,6,7,5,1] k=2
Output[0,3,5]
1+2 + 2+6 + 7+5.

def max_sum_of_3(nums, k):
    n = len(nums); s = [0] * (n - k + 1)
    cur = sum(nums[:k]); s[0] = cur
    for i in range(1, n - k + 1): cur += nums[i + k - 1] - nums[i - 1]; s[i] = cur
    left = [0] * len(s); best = 0
    for i in range(len(s)):
        if s[i] > s[best]: best = i
        left[i] = best
    right = [0] * len(s); best = len(s) - 1
    for i in range(len(s) - 1, -1, -1):
        if s[i] >= s[best]: best = i
        right[i] = best
    ans = None; best_sum = -1
    for j in range(k, len(s) - k):
        l, r = left[j - k], right[j + k]
        t = s[l] + s[j] + s[r]
        if t > best_sum: best_sum = t; ans = [l, j, r]
    return ans
function maxSumOfThreeSubarrays(nums, k) {
  const n = nums.length;
  const s = new Array(n - k + 1); let cur = 0;
  for (let i = 0; i < k; i++) cur += nums[i];
  s[0] = cur;
  for (let i = 1; i < s.length; i++) { cur += nums[i + k - 1] - nums[i - 1]; s[i] = cur; }
  const left = new Array(s.length); let best = 0;
  for (let i = 0; i < s.length; i++) { if (s[i] > s[best]) best = i; left[i] = best; }
  const right = new Array(s.length); best = s.length - 1;
  for (let i = s.length - 1; i >= 0; i--) { if (s[i] >= s[best]) best = i; right[i] = best; }
  let ans = null, bs = -1;
  for (let j = k; j < s.length - k; j++) {
    const l = left[j - k], r = right[j + k];
    const t = s[l] + s[j] + s[r];
    if (t > bs) { bs = t; ans = [l, j, r]; }
  }
  return ans;
}
int[] maxSumOfThreeSubarrays(int[] nums, int k) {
    int n = nums.length, m = n - k + 1; int[] s = new int[m]; int cur = 0;
    for (int i = 0; i < k; i++) cur += nums[i]; s[0] = cur;
    for (int i = 1; i < m; i++) { cur += nums[i + k - 1] - nums[i - 1]; s[i] = cur; }
    int[] L = new int[m]; int best = 0;
    for (int i = 0; i < m; i++) { if (s[i] > s[best]) best = i; L[i] = best; }
    int[] R = new int[m]; best = m - 1;
    for (int i = m - 1; i >= 0; i--) { if (s[i] >= s[best]) best = i; R[i] = best; }
    int[] ans = null; int bs = -1;
    for (int j = k; j < m - k; j++) {
        int l = L[j - k], r = R[j + k]; int t = s[l] + s[j] + s[r];
        if (t > bs) { bs = t; ans = new int[]{l, j, r}; }
    }
    return ans;
}
vector maxSumOfThreeSubarrays(vector& nums, int k) {
    int n = nums.size(), m = n - k + 1; vector s(m); int cur = 0;
    for (int i = 0; i < k; i++) cur += nums[i]; s[0] = cur;
    for (int i = 1; i < m; i++) { cur += nums[i + k - 1] - nums[i - 1]; s[i] = cur; }
    vector L(m); int best = 0;
    for (int i = 0; i < m; i++) { if (s[i] > s[best]) best = i; L[i] = best; }
    vector R(m); best = m - 1;
    for (int i = m - 1; i >= 0; i--) { if (s[i] >= s[best]) best = i; R[i] = best; }
    vector ans; int bs = -1;
    for (int j = k; j < m - k; j++) {
        int l = L[j - k], r = R[j + k]; int t = s[l] + s[j] + s[r];
        if (t > bs) { bs = t; ans = {l, j, r}; }
    }
    return ans;
}
Time: O(n) Space: O(n)