Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2a20e90

Browse files
committed
feat: add solutions to lc problem: No.0209
No.0209.Minimum Size Subarray Sum
1 parent 36ec8ed commit 2a20e90

File tree

8 files changed

+350
-296
lines changed

8 files changed

+350
-296
lines changed

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

Lines changed: 154 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -58,215 +58,228 @@
5858

5959
**方法一:前缀和 + 二分查找**
6060

61-
先求出数组的前缀和 `s`,然后根据 `s[j] - s[i] >= target` => `s[j] >= s[i] + target`,找出最小的一个 j,使得 `s[j]` 满足大于等于 `s[i] + target`,然后更新最小长度即可
61+
我们先预处理出数组 $nums$ 的前缀和数组 $s,ドル其中 $s[i]$ 表示数组 $nums$ 前 $i$ 项元素之和。由于数组 $nums$ 中的元素都是正整数,因此数组 $s$ 也是单调递增的。另外,我们初始化答案 $ans = n + 1,ドル其中 $n$ 为数组 $nums$ 的长度
6262

63-
时间复杂度 $O(NlogN)$。
63+
接下来,我们遍历前缀和数组 $s,ドル对于其中的每个元素 $s[i],ドル我们可以通过二分查找的方法找到满足 $s[j] \geq s[i] + target$ 的最小下标 $j,ドル如果 $j \leq n,ドル则说明存在满足条件的子数组,我们可以更新答案,即 $ans = min(ans, j - i)$。
6464

65-
**方法二:滑动窗口**
65+
最后,如果 $ans \leq n,ドル则说明存在满足条件的子数组,返回 $ans,ドル否则返回 0ドル$。
6666

67-
使用指针 `left`, `right` 分别表示子数组的开始位置和结束位置,维护变量 `sum` 表示子数组 `nums[left...right]` 元素之和。初始时 `left`, `right` 均指向 0。每一次迭代,将 `nums[right]` 加到 `sum`,如果此时 `sum >= target`,更新最小长度即可。然后将 `sum` 减去 `nums[left]`,接着 `left` 指针右移直至 `sum < target`。每一次迭代最后,将 `right` 指针右移
67+
时间复杂度 $O(n \times \log n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度
6868

69-
时间复杂度 $O(N)$。
69+
**方法二:双指针**
70+
71+
我们可以使用双指针 $j$ 和 $i$ 维护一个窗口,其中窗口中的所有元素之和小于 $target$。初始时 $j = 0,ドル答案 $ans = n + 1,ドル其中 $n$ 为数组 $nums$ 的长度。
72+
73+
接下来,指针 $i$ 从 0ドル$ 开始向右移动,每次移动一步,我们将指针 $i$ 对应的元素加入窗口,同时更新窗口中元素之和。如果窗口中元素之和大于等于 $target,ドル说明当前子数组满足条件,我们可以更新答案,即 $ans = min(ans, i - j + 1)$。然后我们不断地从窗口中移除元素 $nums[j],ドル直到窗口中元素之和小于 $target,ドル然后重复上述过程。
74+
75+
最后,如果 $ans \leq n,ドル则说明存在满足条件的子数组,返回 $ans,ドル否则返回 0ドル$。
76+
77+
时间复杂度 $O(n),ドル空间复杂度 $O(1)$。其中 $n$ 为数组 $nums$ 的长度。
7078

7179
<!-- tabs:start -->
7280

7381
### **Python3**
7482

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

77-
前缀和 + 二分查找:
78-
7985
```python
8086
class Solution:
8187
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
82-
s = [0] + list(accumulate(nums))
8388
n = len(nums)
89+
s = list(accumulate(nums, initial=0))
8490
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:
91+
for i, x in enumerate(s):
92+
j = bisect_left(s, x + target)
93+
if j <= n:
8994
ans = min(ans, j - i)
90-
return 0 if ans == n +1else ans
95+
return ans if ans <= n else 0
9196
```
9297

93-
滑动窗口:
94-
9598
```python
9699
class Solution:
97100
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
98101
n = len(nums)
99-
left = right = 0
100-
sum, res = 0, n + 1
101-
while right < n:
102-
sum += nums[right]
103-
while sum >= target:
104-
res = min(res, right - left + 1)
105-
sum -= nums[left]
106-
left += 1
107-
right += 1
108-
return 0 if res == n + 1 else res
102+
ans = n + 1
103+
s = j = 0
104+
for i, x in enumerate(nums):
105+
s += x
106+
while j < n and s >= target:
107+
ans = min(ans, i - j + 1)
108+
s -= nums[j]
109+
j += 1
110+
return ans if ans <= n else 0
109111
```
110112

111113
### **Java**
112114

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

115-
前缀和 + 二分查找:
116-
117117
```java
118118
class Solution {
119119
public int minSubArrayLen(int target, int[] nums) {
120120
int n = nums.length;
121-
int[] s = new int[n + 1];
121+
long[] s = new long[n + 1];
122122
for (int i = 0; i < n; ++i) {
123123
s[i + 1] = s[i] + nums[i];
124124
}
125125
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;
129-
while (left < right) {
130-
int mid = (left + right) >> 1;
131-
if (s[mid] >= t) {
132-
right = mid;
133-
} else {
134-
left = mid + 1;
135-
}
126+
for (int i = 0; i <= n; ++i) {
127+
int j = search(s, s[i] + target);
128+
if (j <= n) {
129+
ans = Math.min(ans, j - i);
136130
}
137-
if (left != n + 1) {
138-
ans = Math.min(ans, left - i);
131+
}
132+
return ans <= n ? ans : 0;
133+
}
134+
135+
private int search(long[] nums, long x) {
136+
int l = 0, r = nums.length;
137+
while (l < r) {
138+
int mid = (l + r) >> 1;
139+
if (nums[mid] >= x) {
140+
r = mid;
141+
} else {
142+
l = mid + 1;
139143
}
140144
}
141-
return ans == n +1?0: ans;
145+
return l;
142146
}
143147
}
144148
```
145149

146-
滑动窗口:
147-
148150
```java
149151
class Solution {
150152
public int minSubArrayLen(int target, int[] nums) {
151153
int n = nums.length;
152-
int left =0, right = 0;
153-
int sum =0, res = n + 1;
154-
while (right < n) {
155-
sum += nums[right];
156-
while (sum >= target) {
157-
res = Math.min(res, right - left + 1);
158-
sum -= nums[left++];
154+
long s = 0;
155+
int ans = n + 1;
156+
for (int i =0, j =0; i < n; ++i) {
157+
s += nums[i];
158+
while (j < n && s >= target) {
159+
ans = Math.min(ans, i - j + 1);
160+
s -= nums[j++];
159161
}
160-
++right;
161162
}
162-
return res == n +1?0 : res;
163+
return ans <= n ? ans : 0;
163164
}
164165
}
165166
```
166167

167168
### **C++**
168169

169-
前缀和 + 二分查找:
170-
171170
```cpp
172171
class Solution {
173172
public:
174173
int minSubArrayLen(int target, vector<int>& nums) {
175174
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;
175+
vector<long long> s(n + 1);
179176
for (int i = 0; i < n; ++i) {
180-
int t = s[i] + target;
181-
auto p = lower_bound(s.begin(), s.end(), t);
182-
if (p != s.end()) {
183-
int j = p - s.begin();
177+
s[i + 1] = s[i] + nums[i];
178+
}
179+
int ans = n + 1;
180+
for (int i = 0; i <= n; ++i) {
181+
int j = lower_bound(s.begin(), s.end(), s[i] + target) - s.begin();
182+
if (j <= n) {
184183
ans = min(ans, j - i);
185184
}
186185
}
187-
return ans == n + 1 ? 0 : ans;
186+
return ans <= n ? ans : 0;
188187
}
189188
};
190189
```
191190
192-
滑动窗口:
193-
194191
```cpp
195192
class Solution {
196193
public:
197194
int minSubArrayLen(int target, vector<int>& nums) {
198-
int left = 0, right;
199-
int sum = 0;
200-
int minlen = INT_MAX;
201-
202-
for (right = 0; right < nums.size(); right++) {
203-
sum += nums[right];
204-
while (left <= right && sum >= target) {
205-
minlen = min(minlen, right - left + 1);
206-
sum -= nums[left++];
195+
int n = nums.size();
196+
long long s = 0;
197+
int ans = n + 1;
198+
for (int i = 0, j = 0; i < n; ++i) {
199+
s += nums[i];
200+
while (j < n && s >= target) {
201+
ans = min(ans, i - j + 1);
202+
s -= nums[j++];
207203
}
208204
}
209-
210-
return minlen == INT_MAX ? 0 : minlen;
205+
return ans == n + 1 ? 0 : ans;
211206
}
212207
};
213208
```
214209

215210
### **Go**
216211

217-
前缀和 + 二分查找:
218-
219212
```go
220213
func minSubArrayLen(target int, nums []int) int {
221214
n := len(nums)
222215
s := make([]int, n+1)
223-
for i, v := range nums {
224-
s[i+1] = s[i] + v
216+
for i, x := range nums {
217+
s[i+1] = s[i] + x
225218
}
226219
ans := n + 1
227-
for i, v := range s {
228-
t := v + target
229-
left, right := 0, n+1
230-
for left < right {
231-
mid := (left + right) >> 1
232-
if s[mid] >= t {
233-
right = mid
234-
} else {
235-
left = mid + 1
236-
}
220+
for i, x := range s {
221+
j := sort.SearchInts(s, x+target)
222+
if j <= n {
223+
ans = min(ans, j-i)
237224
}
238-
if left != n+1 && ans > left-i {
239-
ans = left - i
225+
}
226+
if ans == n+1 {
227+
return 0
228+
}
229+
return ans
230+
}
231+
232+
func min(a, b int) int {
233+
if a < b {
234+
return a
235+
}
236+
return b
237+
}
238+
```
239+
240+
```go
241+
func minSubArrayLen(target int, nums []int) int {
242+
n := len(nums)
243+
s := 0
244+
ans := n + 1
245+
for i, j := 0, 0; i < n; i++ {
246+
s += nums[i]
247+
for s >= target {
248+
ans = min(ans, i-j+1)
249+
s -= nums[j]
250+
j++
240251
}
241252
}
242253
if ans == n+1 {
243254
return 0
244255
}
245256
return ans
246257
}
258+
259+
func min(a, b int) int {
260+
if a < b {
261+
return a
262+
}
263+
return b
264+
}
247265
```
248266

249267
### **C#**
250268

251-
滑动窗口:
252-
253269
```cs
254270
public class Solution {
255271
public int MinSubArrayLen(int target, int[] nums) {
256272
int n = nums.Length;
257-
int left = 0, right = 0;
258-
int sum = 0, res = n + 1;
259-
while (right < n)
260-
{
261-
sum += nums[right];
262-
while (sum >= target)
263-
{
264-
res = Math.Min(res, right - left + 1);
265-
sum -= nums[left++];
273+
long s = 0;
274+
int ans = n + 1;
275+
for (int i = 0, j = 0; i < n; ++i) {
276+
s += nums[i];
277+
while (s >= target) {
278+
ans = Math.Min(ans, i - j + 1);
279+
s -= nums[j++];
266280
}
267-
++right;
268281
}
269-
return res == n + 1 ? 0 : res;
282+
return ans == n + 1 ? 0 : ans;
270283
}
271284
}
272285
```
@@ -276,22 +289,47 @@ public class Solution {
276289
```ts
277290
function minSubArrayLen(target: number, nums: number[]): number {
278291
const n = nums.length;
279-
let res = n + 1;
280-
let sum = 0;
281-
let i = 0;
282-
for (let j = 0; j < n; j++) {
283-
sum += nums[j];
284-
while (sum >= target) {
285-
res = Math.min(res, j - i + 1);
286-
sum -= nums[i];
287-
i++;
292+
const s: number[] = new Array(n + 1).fill(0);
293+
for (let i = 0; i < n; ++i) {
294+
s[i + 1] = s[i] + nums[i];
295+
}
296+
let ans = n + 1;
297+
const search = (x: number) => {
298+
let l = 0;
299+
let r = n + 1;
300+
while (l < r) {
301+
const mid = (l + r) >>> 1;
302+
if (s[mid] >= x) {
303+
r = mid;
304+
} else {
305+
l = mid + 1;
306+
}
307+
}
308+
return l;
309+
};
310+
for (let i = 0; i <= n; ++i) {
311+
const j = search(s[i] + target);
312+
if (j <= n) {
313+
ans = Math.min(ans, j - i);
288314
}
289315
}
316+
return ans === n + 1 ? 0 : ans;
317+
}
318+
```
290319

291-
if (res === n + 1) {
292-
return 0;
320+
```ts
321+
function minSubArrayLen(target: number, nums: number[]): number {
322+
const n = nums.length;
323+
let s = 0;
324+
let ans = n + 1;
325+
for (let i = 0, j = 0; i < n; ++i) {
326+
s += nums[i];
327+
while (s >= target) {
328+
ans = Math.min(ans, i - j + 1);
329+
s -= nums[j++];
330+
}
293331
}
294-
return res;
332+
return ans===n+1?0:ans;
295333
}
296334
```
297335

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /