Skip to content

Commit a4c09aa

Browse files
committed
update 1031 java, cheatsheet/prefix_sum.md
1 parent 848a504 commit a4c09aa

File tree

2 files changed

+150
-26
lines changed

2 files changed

+150
-26
lines changed

doc/cheatsheet/prefix_sum.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ We can use prefix sums. Say P[i+1] = A[0] + A[1] + ... + A[i], where A[i] = 1 if
3232
- LC 560
3333
- Maximum Size Subarray Sum Equals k
3434
- LC 325
35+
- Maximum Sum of Two Non-Overlapping Subarrays
36+
- LC 1031
3537
- Count Number of Nice Subarrays
3638
- LC 1248
3739
- Continuous Subarray Sum (preSum with mod)
@@ -365,4 +367,34 @@ public int maxChunksToSorted_1_1(int[] arr) {
365367
}
366368
return chunks;
367369
}
368-
```
370+
```
371+
372+
### 2-8) Maximum Sum of Two Non-Overlapping Subarrays
373+
374+
```java
375+
// java
376+
// LC 1031
377+
378+
// V1
379+
// https://leetcode.ca/2018-09-26-1031-Maximum-Sum-of-Two-Non-Overlapping-Subarrays/
380+
// IDEA: PREFIX SUM
381+
public int maxSumTwoNoOverlap_1(int[] nums, int firstLen, int secondLen) {
382+
int n = nums.length;
383+
int[] s = new int[n + 1];
384+
for (int i = 0; i < n; ++i) {
385+
s[i + 1] = s[i] + nums[i];
386+
}
387+
int ans = 0;
388+
// case 1) check `firstLen`, then `secondLen`
389+
for (int i = firstLen, t = 0; i + secondLen - 1 < n; ++i) {
390+
t = Math.max(t, s[i] - s[i - firstLen]);
391+
ans = Math.max(ans, t + s[i + secondLen] - s[i]);
392+
}
393+
// case 2) check `secondLen`, then `firstLen`
394+
for (int i = secondLen, t = 0; i + firstLen - 1 < n; ++i) {
395+
t = Math.max(t, s[i] - s[i - secondLen]);
396+
ans = Math.max(ans, t + s[i + firstLen] - s[i]);
397+
}
398+
return ans;
399+
}
400+
```

leetcode_java/src/main/java/LeetCodeJava/Array/MaximumSumOfTwoNonOverlappingSubarrays.java

Lines changed: 117 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,127 @@
4242
*/
4343
public class MaximumSumOfTwoNonOverlappingSubarrays {
4444

45-
// V0
46-
// public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) {
47-
//
48-
// }
45+
// V0
46+
// public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) {
47+
//
48+
// }
49+
50+
// V0-1
51+
// IDEA: PREFIX SUM
52+
/**
53+
* Does This Cover All Configurations?
54+
*
55+
* Yes, it does. By handling the two cases separately, the algorithm ensures:
56+
* • All valid configurations are checked:
57+
* • firstLen subarray is before secondLen.
58+
* • secondLen subarray is before firstLen.
59+
* • There’s no need to explicitly consider cases where:
60+
* • secondLen subarray comes before firstLen in the “case 1” loop because “case 2” handles that.
61+
* • Similarly, the converse is true for “case 2”.
62+
*
63+
*/
64+
public int maxSumTwoNoOverlap_0_1(int[] nums, int firstLen, int secondLen) {
65+
int n = nums.length;
66+
int[] s = new int[n + 1];
67+
for (int i = 0; i < n; ++i) {
68+
s[i + 1] = s[i] + nums[i];
69+
}
70+
int ans = 0;
71+
72+
/**
73+
* where end is exclusive and start is inclusive.
74+
* 2. Two Cases:
75+
* • Case 1: Calculate the maximum sum when a subarray of length firstLen
76+
* comes before a subarray of length secondLen.
77+
*
78+
* • Case 2: Calculate the maximum sum when a subarray of length secondLen
79+
* comes before a subarray of length firstLen.
80+
*
81+
*
82+
*/
83+
84+
// case 1) check `firstLen`, then `secondLen`
85+
for (int i = firstLen, t = 0; i + secondLen - 1 < n; ++i) {
86+
/**
87+
* - Logic:
88+
*
89+
* 1. Start at index i = firstLen because the first subarray
90+
* must be at least firstLen long.
91+
*
92+
* 2. Use t to track the maximum sum of a subarray of length firstLen
93+
* ending at or before index i.
94+
*
95+
* 3. Add the sum of a subarray of length secondLen starting at index i
96+
* and update ans with the combined sum.
97+
*
98+
*
99+
* NOTE !!!
100+
*
101+
*
102+
* - In this case:
103+
* - The loop ensures the first subarray (firstLen) is placed before the second subarray (secondLen).
104+
* - The variable t keeps track of the maximum sum of the firstLen subarray that ends before the second subarray starts at index i.
105+
* - Important Note:
106+
* - The secondLen subarray must always start after the firstLen subarray ends because the iteration proceeds sequentially.
107+
*/
108+
t = Math.max(t, s[i] - s[i - firstLen]); // Maximum sum of `firstLen` ending at or before `i`
109+
ans = Math.max(ans, t + s[i + secondLen] - s[i]); // Combine with `secondLen` starting at `i`
110+
}
111+
// case 2) check `secondLen`, then `firstLen`
112+
113+
/**
114+
* - Logic
115+
*
116+
* * 1. Start at index i = secondLen because the first subarray must be at least secondLen long.
117+
* * 2. Use t to track the maximum sum of a subarray of length secondLen ending at or before index i.
118+
* * 3. Add the sum of a subarray of length firstLen starting at index i and update ans with the combined sum.
119+
*
120+
* - Goal: Calculate the maximum sum where a subarray of length secondLen comes before a subarray of length firstLen.
121+
*
122+
* NOTE !!!
123+
*
124+
* - In this case:
125+
* - The loop ensures the first subarray (secondLen) is placed before the second subarray (firstLen).
126+
* - The variable t keeps track of the maximum sum of the secondLen subarray that ends before the first subarray starts at index i.
127+
* - Important Note:
128+
* - The firstLen subarray must always start after the secondLen subarray ends because the iteration proceeds sequentially.
129+
*
130+
*/
131+
for (int i = secondLen, t = 0; i + firstLen - 1 < n; ++i) {
132+
t = Math.max(t, s[i] - s[i - secondLen]);
133+
ans = Math.max(ans, t + s[i + firstLen] - s[i]);
134+
}
135+
return ans;
136+
}
137+
49138

50139
// V1
140+
// https://leetcode.ca/2018-09-26-1031-Maximum-Sum-of-Two-Non-Overlapping-Subarrays/
141+
// IDEA: PREFIX SUM
142+
public int maxSumTwoNoOverlap_1(int[] nums, int firstLen, int secondLen) {
143+
int n = nums.length;
144+
int[] s = new int[n + 1];
145+
for (int i = 0; i < n; ++i) {
146+
s[i + 1] = s[i] + nums[i];
147+
}
148+
int ans = 0;
149+
// case 1) check `firstLen`, then `secondLen`
150+
for (int i = firstLen, t = 0; i + secondLen - 1 < n; ++i) {
151+
t = Math.max(t, s[i] - s[i - firstLen]);
152+
ans = Math.max(ans, t + s[i + secondLen] - s[i]);
153+
}
154+
// case 2) check `secondLen`, then `firstLen`
155+
for (int i = secondLen, t = 0; i + firstLen - 1 < n; ++i) {
156+
t = Math.max(t, s[i] - s[i - secondLen]);
157+
ans = Math.max(ans, t + s[i + firstLen] - s[i]);
158+
}
159+
return ans;
160+
}
161+
162+
// V1-2
51163
// IDEA: PREFIX SUM
52164
// https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays/solutions/1489581/java-easy-to-understand-prefix-sum-by-rm-5d2z/
53-
public int maxSumTwoNoOverlap_1(int[] A, int L, int M) {
165+
public int maxSumTwoNoOverlap_1_2(int[] A, int L, int M) {
54166
int sums[] = new int[A.length + 1];
55167

56168
for (int i = 1; i <= A.length; i++)
@@ -155,24 +267,4 @@ public int maxSumTwoNoOverlap_3(int[] A, int L, int M) {
155267
return ans;
156268
}
157269

158-
// V5
159-
// https://leetcode.ca/2018-09-26-1031-Maximum-Sum-of-Two-Non-Overlapping-Subarrays/
160-
public int maxSumTwoNoOverlap_5(int[] nums, int firstLen, int secondLen) {
161-
int n = nums.length;
162-
int[] s = new int[n + 1];
163-
for (int i = 0; i < n; ++i) {
164-
s[i + 1] = s[i] + nums[i];
165-
}
166-
int ans = 0;
167-
for (int i = firstLen, t = 0; i + secondLen - 1 < n; ++i) {
168-
t = Math.max(t, s[i] - s[i - firstLen]);
169-
ans = Math.max(ans, t + s[i + secondLen] - s[i]);
170-
}
171-
for (int i = secondLen, t = 0; i + firstLen - 1 < n; ++i) {
172-
t = Math.max(t, s[i] - s[i - secondLen]);
173-
ans = Math.max(ans, t + s[i + firstLen] - s[i]);
174-
}
175-
return ans;
176-
}
177-
178270
}

0 commit comments

Comments
 (0)