二分查找算法是一个基本但用处十分广泛的算法,但要写出一个没有bug的二分查找算法也不容易,《编程珠玑》一书中提到仅有百分之十的人可以第一次就写出没有bug的二分查找算法,主要原因在于寻找中间区间时数据有可能溢出,以及区间的选择不正确导致死循环,数组越界等等。二分查找算法一共有64种形式,由于在计算机中左闭右开区间非常普遍(比如迭代器中就是使用左闭右开区间),我将划分范围划分为左闭右开区间。如下图所示
(1)左闭右开区间
也就是将区间分为三部分:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size(); //这里指向最后一个元素的后一个元素
int mid = 0;
while (left < right) {
mid = left + ((right - left) >> 1);
if(target < nums.at(mid)) //如果小于num[mid],那么target在区间[left,mid)之间
right = mid;
else if (target > nums.at(mid)) //如果大于num[mid],那么target在区间[mid+1,right)之间
left = mid + 1;
else //如果等于num[mid],那么直接返回
return mid;
}
return left; //如果未找到则返回最接近的位置
}
对应的一种在算法中提到的对称区间的情况,和上面的思想一样,只不过区间换成了左闭右闭区间:
(2)左闭右闭区间:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;