1. 长度最小的子数组

题目描述

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度**。**如果不存在符合条件的子数组,返回 0

示例 1:

1
2
3
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

1
2
输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

1
2
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int ans = n + 1;
int sum = 0; // 子数组元素和
int left = 0;
for (int right = 0; right < n; right++) {
// 一直往右遍历
sum += nums[right];
while (sum - nums[left] >= target) { // 如果可以减去左端,来缩小子数组大小
sum -= nums[left];
left++;
}
if (sum >= target) {
// 同时更新最小窗口数
ans = Math.min(ans, right - left + 1);
}
}
return ans <= n ? ans : 0;
}
}

优化

只要达到target ,就更新最小数组长度,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int right = 0;
int res = Integer.MAX_VALUE;
int sum = 0;
while(right < nums.length) {
sum += nums[right];
right++;
while(sum >= target) {
res = Math.min(res, right - left);
sum -= nums[left];
left++;
}
}

return res == Integer.MAX_VALUE ? 0 : res;
}
}