Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 935ac39

Browse files
authored
feat: add solutions to lc problem: No.0689 (doocs#1982)
No.0689.Maximum Sum of 3 Non-Overlapping Subarrays
1 parent e720d2b commit 935ac39

File tree

7 files changed

+645
-97
lines changed

7 files changed

+645
-97
lines changed

solution/0600-0699/0689.Maximum Sum of 3 Non-Overlapping Subarrays/README.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,22 @@
4242

4343
<!-- 这里可写通用的实现逻辑 -->
4444

45+
**方法一:滑动窗口**
46+
4547
滑动窗口,枚举第三个子数组的位置,同时维护前两个无重叠子数组的最大和及其位置。
4648

49+
时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。
50+
51+
**方法二:预处理前后缀 + 枚举中间子数组**
52+
53+
我们可以预处理得到数组 $nums$ 的前缀和数组 $s$,其中 $s[i] = \sum_{j=0}^{i-1} nums[j]$,那么对于任意的 $i$,$j$,$s[j] - s[i]$ 就是子数组 $[i, j)$ 的和。
54+
55+
接下来,我们使用动态规划的方法,维护两个长度为 $n$ 的数组 $pre$ 和 $suf$,其中 $pre[i]$ 表示 $[0, i]$ 范围内长度为 $k$ 的子数组的最大和及其起始位置,$suf[i]$ 表示 $[i, n)$ 范围内长度为 $k$ 的子数组的最大和及其起始位置。
56+
57+
然后,我们枚举中间子数组的起始位置 $i$,那么三个子数组的和就是 $pre[i-1][0] + suf[i+k][0] + (s[i+k] - s[i])$,其中 $pre[i-1][0]$ 表示 $[0, i-1]$ 范围内长度为 $k$ 的子数组的最大和,$suf[i+k][0]$ 表示 $[i+k, n)$ 范围内长度为 $k$ 的子数组的最大和,$(s[i+k] - s[i])$ 表示 $[i, i+k)$ 范围内长度为 $k$ 的子数组的和。我们找出和的最大值对应的三个子数组的起始位置即可。
58+
59+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
60+
4761
<!-- tabs:start -->
4862

4963
### **Python3**
@@ -77,6 +91,36 @@ class Solution:
7791
return ans
7892
```
7993

94+
```python
95+
class Solution:
96+
def maxSumOfThreeSubarrays(self, nums: List[int], k: int) -> List[int]:
97+
n = len(nums)
98+
s = list(accumulate(nums, initial=0))
99+
pre = [[] for _ in range(n)]
100+
suf = [[] for _ in range(n)]
101+
t = idx = 0
102+
for i in range(n - k + 1):
103+
if (cur := s[i + k] - s[i]) > t:
104+
pre[i + k - 1] = [cur, i]
105+
t, idx = pre[i + k - 1]
106+
else:
107+
pre[i + k - 1] = [t, idx]
108+
t = idx = 0
109+
for i in range(n - k, -1, -1):
110+
if (cur := s[i + k] - s[i]) >= t:
111+
suf[i] = [cur, i]
112+
t, idx = suf[i]
113+
else:
114+
suf[i] = [t, idx]
115+
t = 0
116+
ans = []
117+
for i in range(k, n - 2 * k + 1):
118+
if (cur := s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]) > t:
119+
ans = [pre[i - 1][1], i, suf[i + k][1]]
120+
t = cur
121+
return ans
122+
```
123+
80124
### **Java**
81125

82126
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -116,6 +160,49 @@ class Solution {
116160
}
117161
```
118162

163+
```java
164+
class Solution {
165+
public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
166+
int n = nums.length;
167+
int[] s = new int[n + 1];
168+
for (int i = 0; i < n; ++i) {
169+
s[i + 1] = s[i] + nums[i];
170+
}
171+
int[][] pre = new int[n][0];
172+
int[][] suf = new int[n][0];
173+
for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
174+
int cur = s[i + k] - s[i];
175+
if (cur > t) {
176+
pre[i + k - 1] = new int[] {cur, i};
177+
t = cur;
178+
idx = i;
179+
} else {
180+
pre[i + k - 1] = new int[] {t, idx};
181+
}
182+
}
183+
for (int i = n - k, t = 0, idx = 0; i >= 0; --i) {
184+
int cur = s[i + k] - s[i];
185+
if (cur >= t) {
186+
suf[i] = new int[] {cur, i};
187+
t = cur;
188+
idx = i;
189+
} else {
190+
suf[i] = new int[] {t, idx};
191+
}
192+
}
193+
int[] ans = new int[0];
194+
for (int i = k, t = 0; i < n - 2 * k + 1; ++i) {
195+
int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
196+
if (cur > t) {
197+
ans = new int[] {pre[i - 1][1], i, suf[i + k][1]};
198+
t = cur;
199+
}
200+
}
201+
return ans;
202+
}
203+
}
204+
```
205+
119206
### **C++**
120207

121208
```cpp
@@ -154,6 +241,55 @@ public:
154241
};
155242
```
156243
244+
```cpp
245+
class Solution {
246+
public:
247+
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
248+
int n = nums.size();
249+
vector<int> s(n + 1, 0);
250+
for (int i = 0; i < n; ++i) {
251+
s[i + 1] = s[i] + nums[i];
252+
}
253+
254+
vector<vector<int>> pre(n, vector<int>(2, 0));
255+
vector<vector<int>> suf(n, vector<int>(2, 0));
256+
257+
for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
258+
int cur = s[i + k] - s[i];
259+
if (cur > t) {
260+
pre[i + k - 1] = {cur, i};
261+
t = cur;
262+
idx = i;
263+
} else {
264+
pre[i + k - 1] = {t, idx};
265+
}
266+
}
267+
268+
for (int i = n - k, t = 0, idx = 0; i >= 0; --i) {
269+
int cur = s[i + k] - s[i];
270+
if (cur >= t) {
271+
suf[i] = {cur, i};
272+
t = cur;
273+
idx = i;
274+
} else {
275+
suf[i] = {t, idx};
276+
}
277+
}
278+
279+
vector<int> ans;
280+
for (int i = k, t = 0; i < n - 2 * k + 1; ++i) {
281+
int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
282+
if (cur > t) {
283+
ans = {pre[i - 1][1], i, suf[i + k][1]};
284+
t = cur;
285+
}
286+
}
287+
288+
return ans;
289+
}
290+
};
291+
```
292+
157293
### **Go**
158294

159295
```go
@@ -189,6 +325,102 @@ func maxSumOfThreeSubarrays(nums []int, k int) []int {
189325
}
190326
```
191327

328+
```go
329+
func maxSumOfThreeSubarrays(nums []int, k int) (ans []int) {
330+
n := len(nums)
331+
s := make([]int, n+1)
332+
for i := 0; i < n; i++ {
333+
s[i+1] = s[i] + nums[i]
334+
}
335+
336+
pre := make([][]int, n)
337+
suf := make([][]int, n)
338+
339+
for i, t, idx := 0, 0, 0; i < n-k+1; i++ {
340+
cur := s[i+k] - s[i]
341+
if cur > t {
342+
pre[i+k-1] = []int{cur, i}
343+
t, idx = cur, i
344+
} else {
345+
pre[i+k-1] = []int{t, idx}
346+
}
347+
}
348+
349+
for i, t, idx := n-k, 0, 0; i >= 0; i-- {
350+
cur := s[i+k] - s[i]
351+
if cur >= t {
352+
suf[i] = []int{cur, i}
353+
t, idx = cur, i
354+
} else {
355+
suf[i] = []int{t, idx}
356+
}
357+
}
358+
359+
for i, t := k, 0; i < n-2*k+1; i++ {
360+
cur := s[i+k] - s[i] + pre[i-1][0] + suf[i+k][0]
361+
if cur > t {
362+
ans = []int{pre[i-1][1], i, suf[i+k][1]}
363+
t = cur
364+
}
365+
}
366+
367+
return
368+
}
369+
```
370+
371+
### **TypeScript**
372+
373+
```ts
374+
function maxSumOfThreeSubarrays(nums: number[], k: number): number[] {
375+
const n: number = nums.length;
376+
const s: number[] = Array(n + 1).fill(0);
377+
378+
for (let i = 0; i < n; ++i) {
379+
s[i + 1] = s[i] + nums[i];
380+
}
381+
382+
const pre: number[][] = Array(n)
383+
.fill([])
384+
.map(() => new Array(2).fill(0));
385+
const suf: number[][] = Array(n)
386+
.fill([])
387+
.map(() => new Array(2).fill(0));
388+
389+
for (let i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
390+
const cur: number = s[i + k] - s[i];
391+
if (cur > t) {
392+
pre[i + k - 1] = [cur, i];
393+
t = cur;
394+
idx = i;
395+
} else {
396+
pre[i + k - 1] = [t, idx];
397+
}
398+
}
399+
400+
for (let i = n - k, t = 0, idx = 0; i >= 0; --i) {
401+
const cur: number = s[i + k] - s[i];
402+
if (cur >= t) {
403+
suf[i] = [cur, i];
404+
t = cur;
405+
idx = i;
406+
} else {
407+
suf[i] = [t, idx];
408+
}
409+
}
410+
411+
let ans: number[] = [];
412+
for (let i = k, t = 0; i < n - 2 * k + 1; ++i) {
413+
const cur: number = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
414+
if (cur > t) {
415+
ans = [pre[i - 1][1], i, suf[i + k][1]];
416+
t = cur;
417+
}
418+
}
419+
420+
return ans;
421+
}
422+
```
423+
192424
### **...**
193425

194426
```

0 commit comments

Comments
 (0)