给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1.前缀和加二分 O(nlogn)
class Solution {
public:
int minSubArrayLen(int s, vector& nums) {
int n = nums.size();
vector presum(n + 1, 0);
presum[0] = 0;
for (int i = 1; i <= n; i++){
presum[i] = presum[i - 1] + nums[i - 1];
}
int l = 1, r = n;
while (l <= r){
int mid = (l + r) / 2;
if (check(mid, presum, n, s)){
r = mid - 1;
}
else{
l = mid + 1;
}
}
if (check(l - 1, presum, n, s)) return l - 1;
if (check(l, presum, n, s)) return l;
return 0;
}
bool check(int len, vector presum, int n, int s){
for (int i = 0; i < n - len + 1; i++){
if(presum[i + len] - presum[i] >= s){
return true;
}
}
return false;
}
};
2.双指针
class Solution {
public:
int minSubArrayLen(int s, vector& nums) {
int n = nums.size();
int ans = INT_MAX;
int l = 0, r = 0;
int sum = 0;
while (r < n){
sum += nums[r];
while (sum >= s){
ans = min(ans, r - l + 1);
sum -=nums[l];
l++;
}
r++;
}
return ans == INT_MAX ? 0 : ans;
}
};