58
58
59
59
** 方法一:前缀和 + 二分查找**
60
60
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$ 的长度 。
62
62
63
- 时间复杂度 $O(NlogN )$。
63
+ 接下来,我们遍历前缀和数组 $s$,对于其中的每个元素 $s [ i ] $,我们可以通过二分查找的方法找到满足 $s [ j ] \geq s [ i ] + target$ 的最小下标 $j$,如果 $j \leq n$,则说明存在满足条件的子数组,我们可以更新答案,即 $ans = min(ans, j - i )$。
64
64
65
- ** 方法二:滑动窗口 **
65
+ 最后,如果 $ans \leq n$,则说明存在满足条件的子数组,返回 $ans$,否则返回 $0$。
66
66
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$ 的长度 。
68
68
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$ 的长度。
70
78
71
79
<!-- tabs:start -->
72
80
73
81
### ** Python3**
74
82
75
83
<!-- 这里可写当前语言的特殊实现逻辑 -->
76
84
77
- 前缀和 + 二分查找:
78
-
79
85
``` python
80
86
class Solution :
81
87
def minSubArrayLen (self , target : int , nums : List[int ]) -> int :
82
- s = [0 ] + list (accumulate(nums))
83
88
n = len (nums)
89
+ s = list (accumulate(nums, initial = 0 ))
84
90
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:
89
94
ans = min (ans, j - i)
90
- return 0 if ans == n + 1 else ans
95
+ return ans if ans <= n else 0
91
96
```
92
97
93
- 滑动窗口:
94
-
95
98
``` python
96
99
class Solution :
97
100
def minSubArrayLen (self , target : int , nums : List[int ]) -> int :
98
101
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
109
111
```
110
112
111
113
### ** Java**
112
114
113
115
<!-- 这里可写当前语言的特殊实现逻辑 -->
114
116
115
- 前缀和 + 二分查找:
116
-
117
117
``` java
118
118
class Solution {
119
119
public int minSubArrayLen (int target , int [] nums ) {
120
120
int n = nums. length;
121
- int [] s = new int [n + 1 ];
121
+ long [] s = new long [n + 1 ];
122
122
for (int i = 0 ; i < n; ++ i) {
123
123
s[i + 1 ] = s[i] + nums[i];
124
124
}
125
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 ;
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);
136
130
}
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 ;
139
143
}
140
144
}
141
- return ans == n + 1 ? 0 : ans ;
145
+ return l ;
142
146
}
143
147
}
144
148
```
145
149
146
- 滑动窗口:
147
-
148
150
``` java
149
151
class Solution {
150
152
public int minSubArrayLen (int target , int [] nums ) {
151
153
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 ++ ];
159
161
}
160
- ++ right;
161
162
}
162
- return res == n + 1 ? 0 : res ;
163
+ return ans <= n ? ans : 0 ;
163
164
}
164
165
}
165
166
```
166
167
167
168
### ** C++**
168
169
169
- 前缀和 + 二分查找:
170
-
171
170
``` cpp
172
171
class Solution {
173
172
public:
174
173
int minSubArrayLen(int target, vector<int >& nums) {
175
174
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);
179
176
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) {
184
183
ans = min(ans, j - i);
185
184
}
186
185
}
187
- return ans == n + 1 ? 0 : ans ;
186
+ return ans <= n ? ans : 0 ;
188
187
}
189
188
};
190
189
```
191
190
192
- 滑动窗口:
193
-
194
191
```cpp
195
192
class Solution {
196
193
public:
197
194
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++];
207
203
}
208
204
}
209
-
210
- return minlen == INT_MAX ? 0 : minlen;
205
+ return ans == n + 1 ? 0 : ans;
211
206
}
212
207
};
213
208
```
214
209
215
210
### ** Go**
216
211
217
- 前缀和 + 二分查找:
218
-
219
212
``` go
220
213
func minSubArrayLen (target int , nums []int ) int {
221
214
n := len (nums)
222
215
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
225
218
}
226
219
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)
237
224
}
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++
240
251
}
241
252
}
242
253
if ans == n+1 {
243
254
return 0
244
255
}
245
256
return ans
246
257
}
258
+
259
+ func min (a , b int ) int {
260
+ if a < b {
261
+ return a
262
+ }
263
+ return b
264
+ }
247
265
```
248
266
249
267
### ** C#**
250
268
251
- 滑动窗口:
252
-
253
269
``` cs
254
270
public class Solution {
255
271
public int MinSubArrayLen (int target , int [] nums ) {
256
272
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 ++ ];
266
280
}
267
- ++ right ;
268
281
}
269
- return res == n + 1 ? 0 : res ;
282
+ return ans == n + 1 ? 0 : ans ;
270
283
}
271
284
}
272
285
```
@@ -276,22 +289,47 @@ public class Solution {
276
289
``` ts
277
290
function minSubArrayLen(target : number , nums : number []): number {
278
291
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 );
288
314
}
289
315
}
316
+ return ans === n + 1 ? 0 : ans ;
317
+ }
318
+ ```
290
319
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
+ }
293
331
}
294
- return res ;
332
+ return ans === n + 1 ? 0 : ans ;
295
333
}
296
334
```
297
335
0 commit comments