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;
	} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值