尺取法裸题,给一串数列和一个S,求数列中的某个大于S的子数列长度最小。
介绍一下尺取法:
尺取法也叫 two pointer ,顾名思义,像尺子一样,一块一块的截取。尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧。用尺取法来优化,可以使复杂度降为O(n)。是不是解释的有点让人纳闷~。。没关系,下面我们通过这个题目来体会尺取法的魅力。
尺取法的整个过程分为4部:
1.初始化左右端点
2.不断扩大右端点,直到满足条件
3.如果第二步中无法满足条件,则终止,否则更新结果
4.将左端点扩大1,然后回到第二步
#include <set> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N=1e5+7; int a[N]; int main() { int T; scanf("%d",&T); while(T--) { int n, s; scanf("%d %d",&n, &s); for(int i=1; i<=n; i++) scanf("%d", &a[i]); int mi=1e9; for(int l=1,r=0,sum=0; r<=n; ++l) { while(r<=n && sum<s) sum+=a[++r]; if(sum>=s) mi=min(mi,r-l+1); sum-=a[l]; } printf("%d\n",mi==1e9 ? 0 : mi); } }