@@ -236,6 +236,67 @@ private int binarySearch(int start, int end, int[] sums, int target) {
236
236
237
237
时间复杂度:` O(nlog(n)) ` 。
238
238
239
+ ` 2020.5.30 ` 更新,感谢 @Yolo 指出,上边的代码虽然 ` AC ` 了,但二分查找是有瑕疵的。
240
+
241
+ 当 ` sums[mid] > target ` 我们不能直接更新 ` end = mid - 1 ` ,因为此时的 ` mid ` 可能是我们要找的解,所以应该改成 ` end = mid ` 。
242
+
243
+ 自己构造了一个反例
244
+
245
+ ``` java
246
+ 59
247
+ [10 , 50 , 5 ]
248
+ ```
249
+
250
+ 这个 ` case ` 在 ` leetcode ` 是过不了的。
251
+
252
+ ![ ] ( https://windliang.oss-cn-beijing.aliyuncs.com/209_2.jpg )
253
+
254
+ 代码改成下边的样子就可以了。
255
+
256
+ ``` java
257
+ public int minSubArrayLen(int s, int [] nums) {
258
+ int n = nums. length;
259
+ if (n == 0 ) {
260
+ return 0 ;
261
+ }
262
+ int [] sums = new int [n];
263
+ sums[0 ] = nums[0 ];
264
+ for (int i = 1 ; i < n; i++ ) {
265
+ sums[i] = nums[i] + sums[i - 1 ];
266
+ }
267
+ int min = Integer . MAX_VALUE ;
268
+ for (int i = 0 ; i < n; i++ ) {
269
+ int s2 = s - nums[i];
270
+ // 二分查找,目标值是 s2 + sums[i]
271
+ int k = binarySearch(i, n - 1 , sums, s2 + sums[i]);
272
+ if (k != - 1 ) {
273
+ min = Math . min(min, k - i + 1 );
274
+ }
275
+
276
+ }
277
+ return min == Integer . MAX_VALUE ? 0 : min;
278
+ }
279
+
280
+ // 寻求刚好大于 target 的 sums 的下标,也就是大于等于 target 所有 sums 中最小的那个
281
+ private int binarySearch(int start, int end, int [] sums, int target) {
282
+ int mid = - 1 ;
283
+ while (start < end) {
284
+ mid = (start + end) >>> 1 ;
285
+ if (sums[mid] >= target) {
286
+ end = mid;
287
+ } else {
288
+ start = mid + 1 ;
289
+ }
290
+ }
291
+ // 是否找到,没有找到返回 -1
292
+ return sums[start] >= target ? start : - 1 ;
293
+ }
294
+ ```
295
+
296
+ 上边还要注意的一点是,我们要找的是大于等于 ` target ` 中** 最小** 的下标,所以当 ` sums[mid] == target ` 的时候不能立刻停止,需要继续查找。
297
+
298
+ 当然这里其实不用管,因为这里的数组是累和数组,并且都是整数,是严格递增的,当找到相等的时候,前一个一定是小于 ` target ` 的。
299
+
239
300
# 解法四 二分查找
240
301
241
302
解法三的二分查找的关键在于 ` sums ` 数组的定义,一般情况下也不会往那方面想。还是在 [ 这里] ( https://leetcode.com/problems/minimum-size-subarray-sum/discuss/59123/O(N)O(NLogN)-solutions-both-O(1)-space ) 看到的解法,另外一种二分的思路,蛮有意思,分享一下。
0 commit comments