搜索区间为闭区间
public static int binarySearch(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = (left + right)/2;
if(nums[mid] == target){
return mid;
}else if(target > nums[mid]){
left = mid + 1;
}else{
right = mid - 1;
}
}
return -1;
}
搜索区间为[0, nums.length-1], 对于给定的mid,区间分为[0,mid-1],mid,[mid+1,nums.length-1]三部分,因此若num[mid]=target则返回,否则搜索左区间,要不然搜索右区间。
搜索区间为开区间
搜索区间为[0, nums.length)。对于给定的mid,搜索区间被分为三份[0, mid),mid,[mid+1,num.length)。由于没有返回语句,下一次搜索的区间相对于上次来说必须要缩小,否则会出现死循环的情况。
- 搜索左侧
搜索左侧时当nums[mid]==target时,要搜索[0,mid)区间,最终找到最左侧元素是要返回left因为此时的区间为[mid,mid)。
public static int binarySerachLeft(int[] nums, int target){
int left = 0;
int right = nums.length;
while (left < right){
int mid = (left + right)/2;
if(target == nums[mid]){
right = mid;//区间为[left, mid),搜索区间缩小了
}else if(target > nums[mid]){
left = mid + 1;//区间为[left, mid),搜索区间缩小了
}else{
right= mid;//区间为[mid + 1, right),搜索区间缩小了
}
}
//需要判断left是否等于nums.length,因为搜索区间为[0, nums.length),
// 当搜索区间为空时得到的区间可能为[nums.length, nums.length)
//不用判断left是否小于0,因为搜索区间为空时得到[0, 0)
return left >= nums.length || nums[left] != target?-1:left;
}
- 搜索右侧
搜索右侧时,当nums[mid] = target时要搜索[mid+1,nums.length)区间,最后返回结果时要返回left-1(因为满足条件就往右搜索,最后返回的left正好是第一个不满足条件的,left - 1是最后一个满足条件的)。
public static int binarySerachRight(int[] nums, int target){
int left = 0;
int right = nums.length;
while (left < right){
int mid = (left + right)/2;
if(target == nums[mid]){
left = mid + 1; //搜索区间为[mid + 1, right) 变小了
}else if(target > nums[mid]){
left = mid+ 1; //搜索区间为[mid + 1, right) 变小了
}else{
right = mid; //搜索区间为[left, mid) 变小了
}
}
//需要判断left是否等于nums.length,因为搜索区间为[0, nums.length),
// 当搜索区间为空时得到的区间可能为[nums.length, nums.length)
//不用判断left是否小于0,因为搜索区间为空时得到[0, 0)
return left - 1 < 0 || nums[left-1] != target?-1:left-1;
}