题意:某穷屌丝为了顺利成为白富美的备胎,准备在一串数字中找到一个最短区间,该区间包含所有出现过的数字。
尺取法一般思路
整个过程分为4布:
1.初始化左右端点
2.不断扩大右端点,直到满足条件
3.如果第二步中无法满足条件(右端点超出大区间),则终止,否则更新结果
4.将左端点扩大1,然后回到第二步
尺取法复杂度为o(n)
该题数字范围较大不能用数组判重,用map和set来代替
#include<stdio.h>
#include<string.h>
#include<map>
#include<set>
int a[1000001];
using namespace std;
int main()
{ int head,end,i,j,k,m,n;
set<int> b;
map<int,int> cnt;
while(~scanf("%d",&n))
{b.clear();
cnt.clear();
for(i=0;i<n;i++)
{scanf("%d",&a[i]);
b.insert(a[i]);
}
int count=b.size();
int sum=n+1;
int cnt1=0;
head=0;end=0;
while(end!=n)
{while(end<n && cnt1<count)
{if(cnt[a[end]]==0)cnt1++;
cnt[a[end]]++;
end++;
}
while(cnt[a[head]]>1)
{cnt[a[head]]--;
head++;
}
if(cnt1==count)
{sum=min(sum,end-head);
cnt[a[head]]--;
head++;
cnt1--;
}
}
printf("%d\n",sum);
}
return 0;
}