LC.209. 长度最小的子数组
方法0:的纯暴力,这里不讲。
方法1:前缀和+二分。
考虑将其转化为具有单调性的前缀和数组,然后枚举区间左端点进行二分找答案即可。
时间复杂度:
class Solution {
public:
int minSubArrayLen(int s, vector<int>& a) {
vector<int>pre(a.size()+1);
for(int i=1;i<=a.size();i++)
pre[i]=pre[i-1]+a[i-1];
int ans=1e9;
for(int i=1;i<=a.size();i++){
int p=lower_bound(pre.begin()+i,pre.end(),s+pre[i-1])-pre.begin();
//printf("i=%d,p=%d\n",i,p);
if(p!=a.size()+1) ans=min(ans,p-i+1);
}
return ans==1e9?0:ans;
}
};
方法2:尺取法&双指针法。
因为区间和具有单调性,考虑枚举区间右端点,然后不断移动左指针至,再进行右指针.
时间复杂度:
class Solution {
public:
int minSubArrayLen(int s, vector<int>& a) {
int st=0,ed=0;
int ans=1e9,sum=0;
while(ed<a.size()){
sum+=a[ed];
while(sum>=s){
ans=min(ans,ed-st+1);
if(ans==1) return 1;
sum-=a[st];
st++;
}
ed++;
}
return ans==1e9?0:ans;
}
};