{
int num[9] = {1,2,3,3,4,4,5,5,7};//测试数据
int L = 0,R = 8;
int target = 5;
//求小于等于target的最后一个数的下标
while(L < R) {
int mid = L + R + 1 >> 1;
if(num[mid] <= target) L = mid;
else R = mid - 1;
}
//求大于等于target的第一个数的下标
while(L < R) {
int mid = L + R >> 1;
if(num[mid] >= target) R = mid ;
else L = mid + 1;
}
//如果if语句内复杂,可以编写一个check语句
例子
解法:可以使用分两次二分找到答案。
1.找到数组的最低点
2.通过nums[nums.length-1] 与 最低点的大小判断target在最低点左边还是右边。重新设置左边界和右边界,在此二分找target即可。
public int search(int[] nums, int target) {
if(nums.length == 0) return -1;
//首先找到最小值
int l = 0,r = nums.length-1;
int end = nums[r];
while(l<r){
int mid = l+r>>1;
if(nums[mid]<=end) r = mid;
else l = mid+1;
}
//判断在那一半边
if(target<=end) r=nums.length-1;
//通过最小值进行分边,在此二分查找
else {
l=0;
r--;
}
while(l<r){
int mid = l+r>>1;
if(nums[mid]>=target) r = mid;
else l=mid+1;
}
if(nums[l]!=target) return -1;
return l;
}