题目:https://vjudge.net/problem/UVA-1608
用滑动窗口的方法把每个不唯一的数的左边和右边挑出来,这样就能找出唯一的数。
加速思想:普通的从左往右遍历会超时,所以选择左右同时进行遍历,次时最坏的情况是唯一元素在中间,相当于把每次
查找缩小了一半,若要查找n个数,那么时间复杂度为(n*logn),大大减小了查找时间。
#include<bits/stdc++.h>
using namespace std;
int a[200005];
int l[2000005],r[2000005];
bool judge(int left,int right){
if(left>=right)
return true;
for(int i=0;i<=(right-left)/2;i++){ //从两边到中间同时走..
if(l[left+i]<left && r[left+i]>right)
return judge(left,left+i-1) && judge(left+i+1,right);
if(l[right-i]<left && r[right-i]>right)
return judge(left,right-i-1) && judge(right-i+1,right);
}
return false;
}
map<int,int> m;
int main(){
int n;
scanf("%d",&n);
while(n--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
m.clear();
for(int i=0;i<n;i++){
if(m.count(a[i])!=0){
l[i]=m[a[i]];
}
else{
l[i]=-1;
}
m[a[i]]=i;
}
m.clear();
for(int i=n-1;i>=0;i--){
if(m.count(a[i])!=0){
r[i]=m[a[i]];
}
else{
r[i]=n;
}
m[a[i]]=i;
}
if(judge(0,n-1))
printf("non-boring\n");
else
printf("boring\n");
}
}