最基本的二分查找算法如下:
左右边界是0 和 n-1;
循环条件是left <= right;
public int search(int[] nums, int target) {
int n = nums.length;
if(n == 0) return -1;
if(n == 1) return nums[0] == target ? 0:-1;
int left = 0;
int right = n-1;
while(left <= right ){
int mid = left + (right - left)/2;
if(nums[mid] == target){
return mid;
}
if(nums[mid] < target){
left = mid + 1;
}else{
right = mid - 1;
}
}
return -1;
}
二分法也经常用来解决寻找有序序列中第一个满足某条件的元素的位置。
注意是右边界是n,而不是n-1;
循环终止条件是left <right,不带等号,这样最后的返回值可以是left,也可是right。因为left=right时循环终止。
力扣 34 题
```handlebars
public int[] searchRange(int[] nums, int target) {
int leftInd = binarySearch(nums,target);
int rightInd = binarySearch2(nums,target) - 1;
if(leftInd <= rightInd && nums[leftInd] == target ){
return new int[]{leftInd,rightInd};
}
return new int[]{-1,-1};
}
//寻找第一个大于等于target的元素位置
public static int binarySearch(int[] nums,int target){
int n = nums.length;
int left = 0,right = n;
while(left < right){//这里不带等号
int mid = left + (right - left)/2;
if(nums[mid] >= target){//target 一定在mid或mid-1处,
right = mid;
}else{
left = mid+1;
}
}
//left = right时停止。
return left;
}
//寻找第一个大于target的元素位置
public static int binarySearch2(int[] nums,int target){
int n = nums.length;
int left = 0,right = n;
while(left < right){//这里不带等号
int mid = left + (right - left)/2;
if(nums[mid] > target){//target 一定在mid或mid-1处,
right = mid;//注意这里是mid,不是mid - 1;
}else{
left = mid+1;
}
}
//left = right时停止。
return left;
}
力扣35题
public int searchInsert(int[] nums, int target) {
//查找第一个等于target的元素索引
int right = nums.length;
int left = 0;
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid] == target) return mid;
if(nums[mid] > target){
right = mid ;
}else{
left = mid + 1;
}
}
return left;
}
这样的写法,即使要查找的元素不是数组内的元素,也可以正确找到元素要插入的位置。