B站课程链接:二分查找为什么总是写错?_哔哩哔哩_bilibili
注:以下为课程截屏及总结
伪代码
划分为红蓝两块
即要找的元素在红蓝边界处,边界左右两边的红蓝块可以被排除
ps:原本都为黑的,通过二分查找来分别拓展红蓝区域
算法的细节问题(正确性证明)
边界值举例说明算法
算法模板流程
举例代码
public class Solution {
public int binSearch(int a[], int target) {
int low = -1, height = a.length; //注意设置为下限的下一个数,和上限的上一个数
while (low + 1 != height) { //通用终止条件
int mid = low + (height - low) / 2;
if (a[mid] == target) {
return mid;
} else if (a[mid] < target) {
low = mid;
} else if (a[mid] > target) {
height = mid;
}
}
// 返回的比给定值大的下标
// 如数组a为:1 2 4 5,查找3,返回的则是下标2(a[2]=4>3>2)
// 即红色区域的下限
// 同理也可返回low,即蓝色区域上限。根据具体需求决定返回值。
return height;
}
}
算法题目应用
代码:
public class Solution {
public int findDuplicate(int[] nums) {
int[] temp = Arrays.copyOf(nums, nums.length);
Arrays.sort(temp);
for (int i = 0; i < nums.length; i++) {
if (binSearch_firstBiggerandEqual(temp, nums[i]) != binSearch_lastBiggerandEqual(temp, nums[i])) {
return nums[i];
}
}
return -1;
}
//找第一个>=target的下标
public int binSearch_firstBiggerandEqual(int[] nums, int target) {
int left = -1, right = nums.length;
int mid;
while (left + 1 != right) {
mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid;
} else if (nums[mid] >= target) {
right = mid;
}
}
return right;
}
//找最后一个>=target的下标
public int binSearch_lastBiggerandEqual(int[] nums, int target) {
int left = -1, right = nums.length;
int mid;
while (left + 1 != right) {
mid = left + (right - left) / 2;
if (nums[mid] <= target) {
left = mid;
} else if (nums[mid] > target) {
right = mid;
}
}
return left;
}
}