题意:一本书中有P页,第i页恰好有一个知识点ai,全书中同一个知识点有可能会被多次提到,请求出覆盖所有的知识点,要阅读的最少页数(必须是连续的书页)。
解法:根据题意分析符合追逐法的性质,由于知识点ai是整数范围的,需要用一个map作为映射(hash应该也可以,不过代码会长些吧)。依然是维护一个右指针,并及时更新当前区间内的知识点数,保证等于总知识点数。
代码:
/****************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
using namespace std;
#define eps 1e-8
typedef long long LL;
map<int , int> maps;
map<int , int> maps1;
int p;
int num[1000010];
int main()
{
scanf("%d",&p);
for(int i=0; i<p; i++)
{
scanf("%d",num+i);
maps1[num[i]]++;
}
int sum=maps1.size();
int ans=p;
int right=0;
int s=0;
for(int i=0; i<p; i++)
{
map<int,int >::iterator pp;
if(i>=1)
{
pp=maps.find(num[i-1]);
pp->second--;
if(pp->second==0)
s--;
}
while(s<sum &&(right<p))
{
maps[num[right]]++;
if(maps[num[right]]==1)
s++;
right++;
}
//cout<<s<<endl;
if(s<sum)
break;
ans=min(ans,right-i);
}
cout<<ans<<'\n';
return 0;
}