poj 3320Jessica's Reading Problem 尺取法初探(首尾指针法)

题意:某穷屌丝为了顺利成为白富美的备胎,准备在一串数字中找到一个最短区间,该区间包含所有出现过的数字。

尺取法一般思路

整个过程分为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;
	} 



你可能感兴趣的:(指针,poj,尺取法)