题目描述 Description
给你一个长度为n的数字串,数字串里会包含1-m这些数字。如果连续的一段数字子串包含了1-m这些数字,则称这个数字字串为NUM串。你的任务是求出长度最短的NUM串是什么,只需要输出这个长度即可。
1<=n,m<=200000
输入描述 Input Description
第一行给定n和m。
第二行n个数,表示数字串,数字间用空格隔开。
输出描述 Output Description
如果存在NUM串则输出最短NUM串长度,否则输出“NO”。
样例输入 Sample Input
5 3
1 2 2 3 1
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
各个测试点1s
/* 设l和r序列的左端点和右端点,长度即为r-l+1,先使r增加,并且统计每个数字出现的次数,1~m都凑齐后,再使l增加,当一个数字出现1次以上时,就可以抛弃它,直到某个数字只出现过一次,一定要边循环边判断,因为在循环的过程中,不断有满足在1~m中的数字添进来,所以最优解是不断更新的。 */ #include<cstdio> #include<iostream> #define M 200010 #define INF 0x3f3f3f3f using namespace std; int a[M],sum[M]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int l=1,cnt=0,ans=INF; for(int r=1;r<=n;r++) { if(a[r]<1||a[r]>m)continue; if(!sum[a[r]])cnt++; sum[a[r]]++; if(cnt==m) { for(int i=l;i<=n;i++) { if(sum[a[i]]>1) { sum[a[i]]--; l++; } else break; } ans=min(ans,r-l+1); } } if(cnt!=m)printf("NO"); else printf("%d",ans); return 0; }
时间: 2024-09-30 07:20:08