要求复杂度为logn,只能用二分法。
二分有递归和非递归两种方式。
一开始想的的非递归的实现方式,用二分法找到这个数后,然后从这个位置出发,分别向左,向右遍历,找到这个数出现的范围。
注意找到这个数之后,就要跳出循环。二分法查找的循环条件是low<=high,不能忘记等于。
public int[] searchRange(int[] A, int target) {
int len=A.length;
int[] ret={-1,-1};
if(len<1)return ret;
int low=0,high=len-1,middle=0;
while(low<=high){
middle = (low+high)/2;
if(A[middle]==target){
int left=middle-1;
if(left>=0){
while(A[left]==A[middle]){
left--;
if(left<0){
break;
}
}
}
int right=middle+1;
if(right<len){
while(A[right]==A[middle]){
right++;
if(right>=len){
break;
}
}
}
ret[0]=left+1;
ret[1]=right-1;
break;
}else if(A[middle]<target){
low=middle+1;
}else{
high=middle-1;
}
}
return ret;
}
还有一种方法是递归的方法,这是找的网上的方法,也贴出来吧
public int[] searchRange(int[] A, int target) {
int len=A.length;
int[] ret={Integer.MAX_VALUE,Integer.MIN_VALUE};
recSearchRange(A,target,ret,0,len-1);
if(ret[0]==Integer.MAX_VALUE && ret[1]==Integer.MIN_VALUE){
ret[0]=-1;
ret[1]=-1;
}
return ret;
}
void recSearchRange(int[] A,int target,int[] ret,int low,int high){
if(low>high){
return;
}
int middle=(low+high)/2;
if(A[middle] == target){
if(ret[0]>middle){
ret[0]=middle;
}
if(ret[1]<middle){
ret[1]=middle;
}
recSearchRange(A,target,ret,low,middle-1);
recSearchRange(A,target,ret,middle+1,high);
}else if(A[middle] < target){
recSearchRange(A,target,ret,middle+1,high);
}else{
recSearchRange(A,target,ret,low,middle-1);
}
}