思想
判断一个数据是否存在一个有序数组中。 1.二分法。 2.判断数组中间位置的数据是否等于 目标数据。如果等于直接返回true。 3.如果数组中间位置的数据大于 目标数据;说明目标数据 位于左边的一半数据中,重置 R 标记位为mid -1 ; 4.如果数组中间位置的数据小于 目标数据;说明目标数据 位于右边的一半数据中,重置 L 标记位为mid +1 ; 5.循环往复。
代码
public static boolean exist(int[] arr, int targetNum){
if (arr ==null || arr.length ==0){
return false;
}
int L = 0;
int R = arr.length-1;
int mid =0;
while (L< R){
mid = L+(R-L) >>1; //防止溢出
if (arr[mid] == targetNum){
return true;
}else if(arr[mid] > targetNum){ // 中间数据大于目标数据,说明目标数据位于左边
R = mid -1; //重置 右边的边界位
}else { // 中间数据小于目标数据,说明目标数据位于右边
L = mid+1; //重置 右边的边界位
}
}
return arr[L] == targetNum;//防止L=R 的情况。
}
升级一下
在有序数组中,找到最左的 目标数据的下标
例如:12333345 targetNum =3
最左下标为2.
代码
public static int nearestIndex(int[] arr,int targetNum){
int L = 0;
int R = arr.length -1;
int index =-1;
while (L<= R){
int mid = L+(R-L)>>1;
if (arr[mid]>=targetNum){// 不断逼近最左
index = mid;
R = mid-1;
}else {
L =mid+1;
}
}
return index;
}
同理,找到目标数据在数组中的最右的下标。
代码
public static int nearsetRightIndex(int[] arr,int targetNum){
int L =0;
int R = arr.length -1;
int index =-1;
while (L<=R){
int mid = L+(R-L)>>1;
if (arr[mid]<= targetNum){
index = mid;
L = mid+1;
}else {
R = mid-1;
}
}
return index;
}