xinyu04

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

LeetCode 209 Minimum Size Subarray Sum 滑动窗口 & 二分答案

Given an array of positive integers nums and a positive integer target, return the minimal length of a contiguous subarray [numsl, numsl+1, ..., numsr-1, numsr] of which the sum is greater than or equal to target. If there is no such subarray, return 0 instead.

Solution

求最小的序列长度满足区间和 target.

1. O(n)

和上一道题类似,利用滑动窗口的思想。我们用 cur 记录当前的 sum,如果满足 curtarget, 就不断缩短左端点 l, 然后更新答案。

点击查看代码
class Solution {
private:
int ans = INT_MAX;
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int l=0,r=0;
int cur=0;
while(r<n){
cur+=nums[r];
while(cur>=target){
ans=min(ans,r-l+1);
cur-=nums[l];l++;
}
r++;
}
return ((ans==INT_MAX)?0:ans);
}
};

2. O(nlogn)

考虑前缀和 sum:

sum[i]=sum[i1]+nums[i]

我们从后往前遍历,然后利用 upper_bound 来求出 j 满足:

sum[j]>sum[i]s

改写一下得到:

sum[i]sum[j]<s

除此以外,我们还有:

sum[i]sum[j1]s

因此 nums[i]nums[j] 是区间答案。

点击查看代码
class Solution {
private:
int ans = INT_MAX;
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
vector<int> sum(n+1,0);
for(int i=0;i<n;i++){
sum[i+1] = sum[i]+nums[i];
}
// find a j : sum[j] > sum[i]-s
// ---> sum[i]-sum[j]<s && sum[i]-sum[j-1]>=s
// therefore: minimum length: i-j+1
for(int i=n;i>=1;i--){
if(sum[i]>=target){
int j = upper_bound(sum.begin(),sum.end(),sum[i]-target)-sum.begin();
ans=min(ans,i-j+1);
}
}
return ((ans==INT_MAX)?0:ans);
}
};

posted on   Blackzxy  阅读(23)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示