首页 > 其他分享 >1031. 两个非重叠子数组的最大和

1031. 两个非重叠子数组的最大和

时间:2023-04-26 18:11:26浏览次数:56  
标签:重叠 int res firstLen 数组 secondLen 1031 mx

题目链接:1031. 两个非重叠子数组的最大和

方法:前缀和 + 哈兮

解题思路

  • 考虑暴力解法,枚举以 \(i\) 结尾的长度为 \(firstLen\) 的子数组,求 \([i + 1, n - 1]\) 中长度为 \(secondLen\) 长度的子数组和的最大值,最后取两者和的最大值;
  • 优化:前缀和 + 哈兮
    • 假设 \(firstLen\) 在 \(secondLen\) 的左边;
    • 可以初始化一个数组 \(left\) ,\(left[i]\) 表示 \([0, i]\) 中长度为 \(firstLen\) 的子数组的最大值,然后从右向左枚举长度为 \(secondLen\) 的子数组的左端点,计算当前长度为 \(secondLen\) 的子数组最大值 \(mx\),\(res = max(res, mx + left[i])\);
    • 然后在计算在右边的情况,两者取最大值。

代码

class Solution {
public:
    int maxSumTwoNoOverlap(vector<int>& nums, int firstLen, int secondLen) {
        int n = nums.size();
        vector<int> s(n + 1);
        for (int i = 1; i <= n; i ++ ) s[i] += s[i - 1] + nums[i - 1];
        function<int(int, int)> getMax = [&](int L, int R) -> int {
            vector<int> left(n + 1);
            for (int i = L; i <= n; i ++ ) 
                left[i] = max(left[i - 1], s[i] - s[i - L]);
            int res = 0, mx = 0;
            for (int j = n - R; j >= 0; j -- ) {
                mx = max(mx, s[j + R] - s[j]);
                res = max(res, mx + left[j]);
            }
            return res;
        };
        return max(getMax(firstLen, secondLen), getMax(secondLen, firstLen));
    }
};

复杂度分析

时间复杂度:\(O(n)\);
空间复杂度:\(O(n)\)。

标签:重叠,int,res,firstLen,数组,secondLen,1031,mx
From: https://www.cnblogs.com/lxycoding/p/17356902.html

相关文章