洛谷P2249 【深基13.例1】查找
最后一个点超时问题:
这道题采用了两次二分法;主要的二分法可以想到,但是找最小下标时也要用二分法容易忽略。
如果采用代码块中的注释for循环最后一个点就会超时,整体复杂度就会变大
比如说如果数列全为1,时间复杂度就会退化成o(1)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,m;
scanf("%d %d",&n,&m);
int a[n+5],i;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
int j=0;
for(i=0;i<m;i++){
int s,f=0,u;
scanf("%d",&s);
int left=0,right=n-1;
while(left<=right){
int middle=(right-left)/2+left;
if(s<a[middle]) right=middle-1;
else if(s>a[middle]) left=middle+1;
else if(s==a[middle]) {
//for(u=middle-1;u>=0;u--)
//if(a[u]!=s) break;
//如果采用此方法寻找最早出现目标数的下标会出现最后一个点超时的问题
if(middle>0&&a[middle-1]==s){
int high=middle,low=0;
while(low<high){
int mid=(high+low)/2;
if(a[mid]==s) high=mid;
if(a[mid]<s) low=mid+1;
}
printf("%d ",high+1);}
else printf("%d ",middle+1);
f=1;
break;
}
}
if(f==0)
printf("-1 ");
}
}