1.基本二分法,在一个升序不重复的队列中找到一个数字
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2; //防止溢出
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if(nums[mid] == target) {
// 直接返回
return mid;
}
}
// 直接返回
return -1;
}
这里要注意的是三种不同的情况,等于的时候输出就可,区间就是[left,right],没有找到直接返回-1
2. 在升序有重复的序列中找到该数组第一次出现的位置(也就是最左边)
int left_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] >= target) {
right = mid;//收缩左侧边界[left,right)
}
}
// 最后要检查 left 越界的情况
if (nums[left] != target)
return -1;
return left;
}
注意三点:
- 应该缩小左边界,想左逼近,当**>=target的时候**,需要right= mid
- 循环条件是left<right
- 返回的是Left
3. 寻找一个有序且重复的队列中,最右侧的目标数字的位置
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] <= target) {
left = mid +1 ;//收缩有边界
} else if (nums[mid] > target) {
right = mid ;
}
}
// 最后要检查 right 越界的情况
if ( nums[right] != target)
return -1;
return left-1;
}
- 需要向右逼近,则当小于等于为一个情况
- 循环条件是left<right
- 有边界为length,不需要进行-1
- 返回的是Left-1