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;
}
};