689. Maximum Sum of 3 Non-Overlapping Subarrays

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.

 

Example:

Input: [1,2,1,2,6,7,5,1], 2
Output: [0, 3, 5]
Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5].
We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger.

 

Note:

  • nums.length will be between 1 and 20000.
  • nums[i] will be between 1 and 65535.
  • k will be between 1 and floor(nums.length / 3).

 

Approach #1: DP. [C++]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
    vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
        int len = nums.size();
        vector<int> sum = {0}, posLeft(len, 0), posRight(len, len-k);
        for (int i : nums) sum.push_back(sum.back()+i);
        for (int i = k, total = sum[k] - sum[0]; i < len; ++i) {
            if (sum[i+1] - sum[i+1-k] > total) {
                total = sum[i+1] - sum[i+1-k];
                posLeft[i] = i + 1 -k;
            } else
                posLeft[i] = posLeft[i-1];
        }
         
        for (int i = len-k-1, total = sum[len] - sum[len-k]; i >= 0; --i) {
            if (sum[i+k] - sum[i] > total) {
                total = sum[i+k] - sum[i];
                posRight[i] = i;
            } else
                posRight[i] = posRight[i+1];
        }
         
        int maxsum = 0;
        vector<int> ans;
        for (int i = k; i <= len-2*k; ++i) {
            int l = posLeft[i-1], r = posRight[i+k];
            int tot = (sum[i+k] - sum[i]) + (sum[l+k] - sum[l]) + (sum[r+k] - sum[r]);
            if (tot > maxsum) {
                maxsum = tot;
                ans = {l, i, r};
            }
        }
         
        return ans;
    }
};

  

Analysis:

The question asks for three non-overlapping intervals with maximum sum of all 3 intervals. If the middle interval is [i, i+k-1], where k <= i <= n-2k, the left intervals. If the middle interval is [i, i+k-1], where k <= i <= n - 2k, the left interval has to be in subrange [0, i-1], ans the right interval is from subrange [i+k, n-1].

 

So the following solution is based on DP.

 

posLeft[i] is the starting index for the left interval in range [0, i];

posRight[i] is the strating index for the right interval in range [i, n-1];

Then we test every possible strating index og middle interval, i.e. k <= i <= n-2k, ans we can get the corresponding left and right max sum intervals easily from DP. and the run time is O(n).

 

Caution. In order to get lexicgraphical smallest order, when there are tow intervals with equal max sum, always select the left most one. So in the code. the is condition is ">=" for right interval due to backward searching, and ">" for left interval. 

 

Reference:

https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/discuss/108231/C%2B%2BJava-DP-with-explanation-O(n)

 

posted @   Veritas_des_Liberty  阅读(203)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
历史上的今天:
2018-03-13 D - Back and Forth(模拟)
2018-03-13 I - 一次元リバーシ / 1D Reversi(水题)
点击右上角即可分享
微信分享提示