这是一道非常典型的滑动窗口问题。我们可以使用双指针来维护一个滑动窗口,用来表示当前考虑的子数组。
一个左指针 l 和一个右指针 r,表示当前窗口的左右边界。我们需要移动右指针 r,扩大窗口,直到窗口中的数字之和大于等于 target 为止。此时,我们可以记录下当前窗口的长度(即 r - l + 1),并尝试将左指针 l 向右移动,缩小窗口。在缩小窗口的过程中,我们需要不断更新记录的长度,直到窗口中的数字之和小于 target 为止。之后,我们可以继续移动右指针 r,扩大窗口,如此反复,直到右指针 r 到达数组的末尾为止。最终得到的最小的窗口长度即为答案。
这个过程类似于我们在橙汁里面加糖,我们需要在窗口里面加入数字,使得窗口中的数字之和大于等于 target。当我们加入的数字多了之后,窗口中的数字之和超过了 target,这时我们需要将窗口的左边界向右移动,减少窗口中的数字之和,直到数字之和小于 target。然后,我们再从右边加入数字,如此反复,直到右边界到达数组末尾。
对于这个过程,我们可以用一个循环来实现,用两个指针 l 和 r 来表示当前窗口的左右边界,一个变量 sum 来表示窗口中的数字之和,一个变量 res 来记录窗口的最小长度。初始时,l 和 r 都指向数组的第一个位置,sum 和 res 都为 0。然后,我们开始循环,首先移动右指针 r,直到窗口中的数字之和大于等于 target,这时我们记录下当前窗口的长度(即 r - l + 1),然后尝试将左指针 l 向右移动,缩小窗口,直到窗口中的数字之和小于 target。在缩小窗口的过程中,我们需要不断更新记录的长度,直到窗口中的数字之和小于 target 为止。然后,我们再移动右指针 r,如此反复,直到右指针 r 到达数组的末尾为止。最终得到的最小的窗口长度即为答案。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int l = 0, r = 0;
int sum = 0;
int res = INT_MAX;
while (r < n) {
sum += nums[r];
while (sum >= target) {
res = min(res, r - l + 1);
sum -= nums[l];
l++;
}
r++;
}
return res == INT_MAX ? 0 : res;
}
};