Skip to content

Commit

Permalink
#1031 动态规划: 求解数组中两个非重叠子数组的最大和, O(n)算法 (azl397985856#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
WinnoChan authored and azl397985856 committed Jun 11, 2019
1 parent fac46b8 commit fc8c6f3
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ The data structures mainly includes:
- [0877.stone-game](./problems/877.stone-game.md)
- [0887.super-egg-drop](./problems/887.super-egg-drop.md)
- [0900.rle-iterator](./problems/900.rle-iterator.md)
- [1031.maximum-sum-of-two-non-overlapping-subarrays](./problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md) 🆕

#### Hard
- [0023.merge-k-sorted-lists](./problems/23.merge-k-sorted-lists.md)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0877.stone-game](./problems/877.stone-game.md)
- [0887.super-egg-drop](./problems/887.super-egg-drop.md)
- [0900.rle-iterator](./problems/900.rle-iterator.md)
- [1031.maximum-sum-of-two-non-overlapping-subarrays](./problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md) 🆕

#### 困难难度
- [0023.merge-k-sorted-lists](./problems/23.merge-k-sorted-lists.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile modified="2019-06-08T14:25:14.475Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" etag="RqJ4FwFVh3-xb2p3-YnX" version="10.7.5" type="github"><diagram id="J-oB_Gyhdbi0Jz0GIsj-" name="Page-1">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</diagram></mxfile>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 106 additions & 0 deletions problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
## 题目地址
https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/

## 题目描述

```
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:
L >= 1
M >= 1
L + M <= A.length <= 1000
0 <= A[i] <= 1000
```

## 思路(动态规划)

题目中要求在前N(数组长度)个数中找出长度分别为L和M的非重叠子数组之和的最大值, 因此, 我们可以定义数组A中前i个数可构成的非重叠子数组L和M的最大值为SUMM[i], 并找到SUMM[i]和SUMM[i-1]的关系, 那么最终解就是SUMM[N]. 以下为图解:

![1031.Maximum Sum of Two Non-Overlapping Subarrays](../assets/problems/1031.maximum-sum-of-two-non-overlapping-subarrays.png)

## 关键点解析

1. 注意图中描述的都是A[i-1], 而不是A[i], 因为base case为空数组, 而不是A[0];
2. 求解图中ASUM数组的时候, 注意定义的是ASUM[i] = sum(A[0:i]), 因此当i等于0时, A[0:0]为空数组, 即: ASUM[0]为0, 而ASUM[1]才等于A[0];
3. 求解图中MAXL数组时, 注意i < L时, 没有意义, 因为长度不够, 所以从i = L时才开始求解;
4. 求解图中MAXM数组时, 也一样, 要从i = M时才开始求解;
5. 求解图中SUMM数组时, 因为我们需要一个L子数组和一个M子数组, 因此长度要大于等于L+M才有意义, 所以要从i = L + M时开始求解.

## 代码

* 语言支持: Python

Python Code:
```python
class Solution:
def maxSumTwoNoOverlap(self, a: List[int], l: int, m: int) -> int:
"""
define asum[i] as the sum of subarray, a[0:i]
define maxl[i] as the maximum sum of l-length subarray in a[0:i]
define maxm[i] as the maximum sum of m-length subarray in a[0:i]
define msum[i] as the maximum sum of non-overlap l-length subarray and m-length subarray
case 1: a[i] is both not in l-length subarray and m-length subarray, then msum[i] = msum[i - 1]
case 2: a[i] is in l-length subarray, then msum[i] = asum[i] - asum[i-l] + maxm[i-l]
case 3: a[i] is in m-length subarray, then msum[i] = asum[i] - asum[i-m] + maxl[i-m]
so, msum[i] = max(msum[i - 1], asum[i] - asum[i-l] + maxl[i-l], asum[i] - asum[i-m] + maxm[i-m])
"""

alen, tlen = len(a), l + m
asum = [0] * (alen + 1)
maxl = [0] * (alen + 1)
maxm = [0] * (alen + 1)
msum = [0] * (alen + 1)

for i in range(tlen):
if i == 1:
asum[i] = a[i - 1]
elif i > 1:
asum[i] = asum[i - 1] + a[i - 1]
if i >= l:
maxl[i] = max(maxl[i - 1], asum[i] - asum[i - l])
if i >= m:
maxm[i] = max(maxm[i - 1], asum[i] - asum[i - m])

for i in range(tlen, alen + 1):
asum[i] = asum[i - 1] + a[i - 1]
suml = asum[i] - asum[i - l]
summ = asum[i] - asum[i - m]
maxl[i] = max(maxl[i - 1], suml)
maxm[i] = max(maxm[i - 1], summ)
msum[i] = max(msum[i - 1], suml + maxm[i - l], summ + maxl[i - m])

return msum[-1]
```

## 扩展

1. 代码中, 求解了4个动态规划数组来求解最终值, 有没有可能只用两个数组来求解该题, 可以的话, 需要保留的又是哪两个数组?
2. 代码中, 求解的4动态规划数组的顺序能否改变, 哪些能改, 哪些不能改?

0 comments on commit fc8c6f3

Please sign in to comment.