首先介绍尺取(双指针)
用于求解满足条件的最小区间问题
首先,从数组最左边元素开始,向右延伸r,使得最初满足条件。此时对于l为1来说,是最小的满足条件区间
接下来,开始将l变为2。变为2后,需要将r延长到能够满足条件的下一个r(可能不用延长,也可以先延长再把l变成2)。这样就得到了l为2时的最小区间(因为r不可缩小了)
以此类推,不断重复以上流程,直到l变为某个值后,再也找不到合适的r使得区间满足条件了。那么从左边界为1到此时的l-1为止中,所记录的区间大小最小的那一个就是我们所求的了,并没有遗漏任何可能的区间。
本题采用此思路即可求解,写得麻烦了些,不足为参考,看上面的思路就行啦
#include<iostream> using namespace std; int a[2005]; int painting[1000005]; int retire=0; int l=1,r=1; int n,m; void initial(){ a[painting[r]]++; retire++; while(retire!=m){ r++; if(a[painting[r]]==0) retire++; a[painting[r]]++; } } int main(){ int need; int ansl,ansr; cin>>n>>m; int min=n+5; for(int i=1;i<=n;i++){ cin>>painting[i]; } initial(); while(l<=r&&r<=n){ while(a[painting[l]]>1){ a[painting[l]]--; l++; } need=painting[l]; if(r-l+1<min){ min=r-l+1; ansl=l; ansr=r; } while(painting[r+1]!=need&&r+1<=n){ r++; a[painting[r]]++; } l++; r++; } cout<<ansl<<' '<<ansr; return 0; }