Skip to content

Commit ffbccc0

Browse files
committed
feat: add solutions to lc problem: No.0209
No.0209.Minimum Size Subarray Sum
1 parent e67f8d6 commit ffbccc0

File tree

4 files changed

+223
-84
lines changed

4 files changed

+223
-84
lines changed

solution/0200-0299/0209.Minimum Size Subarray Sum/README.md

Lines changed: 95 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -56,43 +56,41 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59-
前缀和 + 二分查找”,先求出数组的前缀和 `preSum`,然后根据 `preSum[i] - preSum[j] >= target` => `preSum[i] >= preSum[j] + target`,对 `preSum[i]` 进行二分查找,然后更新最小长度即可。时间复杂度 `O(n logn)`
59+
**方法一:前缀和 + 二分查找**
6060

61-
也可以用“滑动窗口”
61+
先求出数组的前缀和 `s`,然后根据 `s[j] - s[i] >= target` => `s[j] >= s[i] + target`,找出最小的一个 j,使得 `s[j]` 满足大于等于 `s[i] + target`,然后更新最小长度即可
6262

63-
使用指针 left, right 分别表示子数组的开始位置和结束位置,维护变量 sum 表示子数组 `nums[left...right]` 元素之和。初始时 left, right 均指向 0。每一次迭代,将 `nums[right]` 加到 sum,如果此时 `sum >= target`,更新最小长度即可。然后将 sum 减去 `nums[left]`,接着 left 指针右移直至 `sum < target`。每一次迭代最后,将 right 指针右移。时间复杂度 `O(n)`
63+
时间复杂度 `O(n logn)`
64+
65+
**方法二:滑动窗口**
66+
67+
使用指针 left, right 分别表示子数组的开始位置和结束位置,维护变量 sum 表示子数组 `nums[left...right]` 元素之和。初始时 left, right 均指向 0。每一次迭代,将 `nums[right]` 加到 sum,如果此时 `sum >= target`,更新最小长度即可。然后将 sum 减去 `nums[left]`,接着 left 指针右移直至 `sum < target`。每一次迭代最后,将 right 指针右移。
68+
69+
时间复杂度 `O(n)`
6470

6571
<!-- tabs:start -->
6672

6773
### **Python3**
6874

6975
<!-- 这里可写当前语言的特殊实现逻辑 -->
7076

71-
前缀和 + 二分查找”。
77+
前缀和 + 二分查找
7278

7379
```python
7480
class Solution:
7581
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
82+
s = [0] + list(accumulate(nums))
7683
n = len(nums)
77-
pre_sum = [0] * (n + 1)
78-
for i in range(1, n + 1):
79-
pre_sum[i] = pre_sum[i - 1] + nums[i - 1]
80-
res = n + 1
81-
for i in range(1, n + 1):
82-
t = pre_sum[i - 1] + target
83-
left, right = 0, n
84-
while left < right:
85-
mid = (left + right) >> 1
86-
if pre_sum[mid] >= t:
87-
right = mid
88-
else:
89-
left = mid + 1
90-
if pre_sum[left] - pre_sum[i - 1] >= target:
91-
res = min(res, left - i + 1)
92-
return 0 if res == n + 1 else res
84+
ans = n + 1
85+
for i, v in enumerate(s):
86+
t = v + target
87+
j = bisect_left(s, t)
88+
if j != n + 1:
89+
ans = min(ans, j - i)
90+
return 0 if ans == n + 1 else ans
9391
```
9492

95-
滑动窗口”。
93+
滑动窗口
9694

9795
```python
9896
class Solution:
@@ -114,38 +112,38 @@ class Solution:
114112

115113
<!-- 这里可写当前语言的特殊实现逻辑 -->
116114

117-
前缀和 + 二分查找”。
115+
前缀和 + 二分查找
118116

119117
```java
120118
class Solution {
121119
public int minSubArrayLen(int target, int[] nums) {
122120
int n = nums.length;
123-
int[] preSum = new int[n + 1];
124-
for (int i = 1; i <= n; ++i) {
125-
preSum[i] = preSum[i - 1] +nums[i - 1];
121+
int[] s = new int[n + 1];
122+
for (int i = 0; i < n; ++i) {
123+
s[i + 1] = s[i] + nums[i];
126124
}
127-
int res = n + 1;
128-
for (int i = 1; i <= n; ++i) {
129-
int t = preSum[i - 1] + target;
130-
int left = 0, right = n;
125+
int ans = n + 1;
126+
for (int i = 0; i < n; ++i) {
127+
int t = s[i] + target;
128+
int left = 0, right = n + 1;
131129
while (left < right) {
132130
int mid = (left + right) >> 1;
133-
if (preSum[mid] >= t) {
131+
if (s[mid] >= t) {
134132
right = mid;
135133
} else {
136134
left = mid + 1;
137135
}
138136
}
139-
if (preSum[left] - preSum[i - 1] >= target) {
140-
res = Math.min(res, left - i + 1);
137+
if (left != n + 1) {
138+
ans = Math.min(ans, left - i);
141139
}
142140
}
143-
return res == n + 1 ? 0 : res;
141+
return ans == n + 1 ? 0 : ans;
144142
}
145143
}
146144
```
147145

148-
滑动窗口”。
146+
滑动窗口
149147

150148
```java
151149
class Solution {
@@ -168,6 +166,33 @@ class Solution {
168166

169167
### **C++**
170168

169+
前缀和 + 二分查找:
170+
171+
```cpp
172+
class Solution {
173+
public:
174+
int minSubArrayLen(int target, vector<int>& nums) {
175+
int n = nums.size();
176+
vector<int> s(n + 1);
177+
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
178+
int ans = n + 1;
179+
for (int i = 0; i < n; ++i)
180+
{
181+
int t = s[i] + target;
182+
auto p = lower_bound(s.begin(), s.end(), t);
183+
if (p != s.end())
184+
{
185+
int j = p - s.begin();
186+
ans = min(ans, j - i);
187+
}
188+
}
189+
return ans == n + 1 ? 0 : ans;
190+
}
191+
};
192+
```
193+
194+
滑动窗口:
195+
171196
```cpp
172197
class Solution {
173198
public:
@@ -189,8 +214,44 @@ public:
189214
};
190215
```
191216

217+
### **Go**
218+
219+
前缀和 + 二分查找:
220+
221+
```go
222+
func minSubArrayLen(target int, nums []int) int {
223+
n := len(nums)
224+
s := make([]int, n+1)
225+
for i, v := range nums {
226+
s[i+1] = s[i] + v
227+
}
228+
ans := n + 1
229+
for i, v := range s {
230+
t := v + target
231+
left, right := 0, n+1
232+
for left < right {
233+
mid := (left + right) >> 1
234+
if s[mid] >= t {
235+
right = mid
236+
} else {
237+
left = mid + 1
238+
}
239+
}
240+
if left != n+1 && ans > left-i {
241+
ans = left - i
242+
}
243+
}
244+
if ans == n+1 {
245+
return 0
246+
}
247+
return ans
248+
}
249+
```
250+
192251
### **C#**
193252

253+
滑动窗口:
254+
194255
```cs
195256
public class Solution {
196257
public int MinSubArrayLen(int target, int[] nums) {

solution/0200-0299/0209.Minimum Size Subarray Sum/README_EN.md

Lines changed: 90 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,31 @@
4343

4444
## Solutions
4545

46+
**Method 1: PreSum & Binary search**
47+
48+
**Method 2: Slide window**
49+
4650
<!-- tabs:start -->
4751

4852
### **Python3**
4953

50-
Presum and binary search.
54+
PreSum & Binary search:
5155

5256
```python
5357
class Solution:
5458
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
59+
s = [0] + list(accumulate(nums))
5560
n = len(nums)
56-
pre_sum = [0] * (n + 1)
57-
for i in range(1, n + 1):
58-
pre_sum[i] = pre_sum[i - 1] + nums[i - 1]
59-
res = n + 1
60-
for i in range(1, n + 1):
61-
t = pre_sum[i - 1] + target
62-
left, right = 0, n
63-
while left < right:
64-
mid = (left + right) >> 1
65-
if pre_sum[mid] >= t:
66-
right = mid
67-
else:
68-
left = mid + 1
69-
if pre_sum[left] - pre_sum[i - 1] >= target:
70-
res = min(res, left - i + 1)
71-
return 0 if res == n + 1 else res
61+
ans = n + 1
62+
for i, v in enumerate(s):
63+
t = v + target
64+
j = bisect_left(s, t)
65+
if j != n + 1:
66+
ans = min(ans, j - i)
67+
return 0 if ans == n + 1 else ans
7268
```
7369

74-
Slide window.
70+
Slide window:
7571

7672
```python
7773
class Solution:
@@ -91,38 +87,38 @@ class Solution:
9187

9288
### **Java**
9389

94-
Presum and binary search.
90+
Presum & binary search:
9591

9692
```java
9793
class Solution {
9894
public int minSubArrayLen(int target, int[] nums) {
9995
int n = nums.length;
100-
int[] preSum = new int[n + 1];
101-
for (int i = 1; i <= n; ++i) {
102-
preSum[i] = preSum[i - 1] +nums[i - 1];
96+
int[] s = new int[n + 1];
97+
for (int i = 0; i < n; ++i) {
98+
s[i + 1] = s[i] + nums[i];
10399
}
104-
int res = n + 1;
105-
for (int i = 1; i <= n; ++i) {
106-
int t = preSum[i - 1] + target;
107-
int left = 0, right = n;
100+
int ans = n + 1;
101+
for (int i = 0; i < n; ++i) {
102+
int t = s[i] + target;
103+
int left = 0, right = n + 1;
108104
while (left < right) {
109105
int mid = (left + right) >> 1;
110-
if (preSum[mid] >= t) {
106+
if (s[mid] >= t) {
111107
right = mid;
112108
} else {
113109
left = mid + 1;
114110
}
115111
}
116-
if (preSum[left] - preSum[i - 1] >= target) {
117-
res = Math.min(res, left - i + 1);
112+
if (left != n + 1) {
113+
ans = Math.min(ans, left - i);
118114
}
119115
}
120-
return res == n + 1 ? 0 : res;
116+
return ans == n + 1 ? 0 : ans;
121117
}
122118
}
123119
```
124120

125-
Slide window.
121+
Slide window:
126122

127123
```java
128124
class Solution {
@@ -145,6 +141,33 @@ class Solution {
145141

146142
### **C++**
147143

144+
Presum & binary search:
145+
146+
```cpp
147+
class Solution {
148+
public:
149+
int minSubArrayLen(int target, vector<int>& nums) {
150+
int n = nums.size();
151+
vector<int> s(n + 1);
152+
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
153+
int ans = n + 1;
154+
for (int i = 0; i < n; ++i)
155+
{
156+
int t = s[i] + target;
157+
auto p = lower_bound(s.begin(), s.end(), t);
158+
if (p != s.end())
159+
{
160+
int j = p - s.begin();
161+
ans = min(ans, j - i);
162+
}
163+
}
164+
return ans == n + 1 ? 0 : ans;
165+
}
166+
};
167+
```
168+
169+
Slide window:
170+
148171
```cpp
149172
class Solution {
150173
public:
@@ -166,8 +189,44 @@ public:
166189
};
167190
```
168191

192+
### **Go**
193+
194+
Presum & binary search:
195+
196+
```go
197+
func minSubArrayLen(target int, nums []int) int {
198+
n := len(nums)
199+
s := make([]int, n+1)
200+
for i, v := range nums {
201+
s[i+1] = s[i] + v
202+
}
203+
ans := n + 1
204+
for i, v := range s {
205+
t := v + target
206+
left, right := 0, n+1
207+
for left < right {
208+
mid := (left + right) >> 1
209+
if s[mid] >= t {
210+
right = mid
211+
} else {
212+
left = mid + 1
213+
}
214+
}
215+
if left != n+1 && ans > left-i {
216+
ans = left - i
217+
}
218+
}
219+
if ans == n+1 {
220+
return 0
221+
}
222+
return ans
223+
}
224+
```
225+
169226
### **C#**
170227

228+
Slide window:
229+
171230
```cs
172231
public class Solution {
173232
public int MinSubArrayLen(int target, int[] nums) {

0 commit comments

Comments
 (0)