给定长度为n的数列整数a[0],a[1],...a[n-1]以及整数S。求出总和不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。
限制条件
10<n<10^5
0<a[i]<=10^4
S<10^8
思路:(1)以s,t,sum分别代表连续子序列开始位置,结束位置,累加和;
(2)只要依然有sum<S,就不断将sum增加a[t],并将t增加1;
(3)如果无法满足sum>=S则终止。否则的话,更新res=min(res,t-s);
(4)将sum减去a[s](连续子序列头部),同时s增加1,继续(2);
时间复杂度:因为t最多变化n次,因此时间复杂度为O(n);
实质:反复地推进区间的开头与结尾,求取满足条件的最小区间,此方法称为尺取法(因为这种操作很像是尺取虫爬行的方式);
代码:
void solve(){
int res=n+1;
int s=0,t=0,sum=0;
for(;;){
while(t<n&&sum<S)
sum+=a[t++];
if(sum<S) break;
res=min(res,t-s);
sum-=a[s++];
}
if(res>n)
//解不存在
res=0;
printf("%d\n",res);
}