Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 1031. Maximum Sum of Two Non-Overlapping Subarrays #1031

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 1031. Maximum Sum of Two Non-Overlapping Subarrays #1031

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping (contiguous) subarrays, which have lengths L and M.  (For clarification, the L-length subarray could occur before or after the M-length subarray.)

Formally, return the largest V for which V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + ... + A[j+M-1]) and either:

  • 0 <= i < i + L - 1 < j < j + M - 1 < A.length, or
  • 0 <= j < j + M - 1 < i < i + L - 1 < A.length.

Example 1:

Input: A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2
Output: 20
Explanation: One choice of subarrays is [9] with length 1, and [6,5] with length 2.

Example 2:

Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2
Output: 29 Explanation: One choice of subarrays is [3,8,1] with length 3, and [8,9] with length 2.

Example 3:

Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3
Output: 31 Explanation: One choice of subarrays is [5,6,0,9] with length 4, and [3,8] with length 3.

Note:

  1. L >= 1
  2. M >= 1
  3. L + M <= A.length <= 1000
  4. 0 <= A[i] <= 1000

这道题给了一个非负数组A,还有两个长度L和M,说是要分别找出不重叠且长度分别为L和M的两个子数组,前后顺序无所谓,问两个子数组最大的数字之和是多少。博主最开始想的方法是用动态规划 Dynamic Programming 和滑动窗口 Sliding Window 来做,用两个 dp 数组,其中 front[i] 表示范围 [0, i] 之间的长度为M的子数组的最大数字之和,back[i] 表示范围 [i, n-1] 之间的长度为M的子数组的最大数字之和。然后再次遍历数组,维护一个长度为L的滑动数组,当数组长度正好为L的时候,当前窗口的数字之和加上左边的 front[left-1],或者加上右边的 back[i+1],取二者中的较大值来更新结果 res,这种解法可以通过 OJ,但是行数比较多,且用了三个 for 循环,这里就不贴了。来看论坛上的高分解法吧,首先建立累加和数组,这里可以直接覆盖A数组,然后定义 Lmax 为在最后M个数字之前的长度为L的子数组的最大数字之和,同理,Mmax 表示在最后L个数字之前的长度为M的子数组的最大数字之和。结果 res 初始化为前 L+M 个数字之和,然后遍历数组,从 L+M 开始遍历,先更新 Lmax 和 Mmax,其中 Lmax 用 A[i - M] - A[i - M - L] 来更新,Mmax 用 A[i - L] - A[i - M - L] 来更新。然后取 Lmax + A[i] - A[i - M]Mmax + A[i] - A[i - L] 之间的较大值来更新结果 res 即可,参见代码如下:

class Solution {
public:
    int maxSumTwoNoOverlap(vector<int>& A, int L, int M) {
        for (int i = 1; i < A.size(); ++i) {
            A[i] += A[i - 1];
        }
        int res = A[L + M - 1], Lmax = A[L - 1], Mmax = A[M - 1];
        for (int i = L + M; i < A.size(); ++i) {
            Lmax = max(Lmax, A[i - M] - A[i - M - L]);
            Mmax = max(Mmax, A[i - L] - A[i - M - L]);
            res = max(res, max(Lmax + A[i] - A[i - M], Mmax + A[i] - A[i - L]));
        }
        return res;
    }
};

Github 同步地址:

#1031

参考资料:

https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/

https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/discuss/278251/JavaC%2B%2BPython-O(N)Time-O(1)-Space

https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/discuss/279221/JavaPython-3-two-easy-DP-codes-w-comment-time-O(n)-NO-change-of-input

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant