前言
看了acwing y神的视频,学习了整数二分的模板,二分经常会出现死循环、越界等情况,所以将模板记录一下:
1、二分查找(找target值第一次出现的位置)
middle = l + ((r - l)>>1); middle是取得下边界。
默认被查找的数组是升序。
int binarySearch1(vector<int>& nums, int l, int r, int target){
int middle = l + ((r - l)>>1);
while(l < r){
middle = l + ((r - l)>>1);
// 如果结果在middle的左边(包括middle)
if(target <= nums[middle]) r = middle;
else l = middle+1;
}
// 如果找到了
if(nums[l] == target) return l;
// 如果没有找到
return -1;
}
2、二分查找(找target值最后一次出现的位置)
当出现l = middle 赋值的时候,可能出现死循环,所以middle = l + ((r - l + 1)>>1), 在进行除2时需要取上边界。
int binarySearch2(vector<int>& nums, int l, int r, int target){
int middle = l + ((r - l + 1)>>1);
while(l < r){
middle = l + ((r - l + 1)>>1);
if(target >= nums[middle]) l = middle;
else r = middle - 1;
}
if(nums[l] == target) return l;
return -1;
}
3、二分查找(判断某个值是否出现过)
其实用模板1和模板2都能实现 只是感觉结果可以在while中提前返回出来,所以我又单独写一个模板3。
bool binarySearch(vector<int>& nums, int l, int r, int target){
int middle = l + ((r - l)>>1);
while(l <= r){
middle = l + ((r - l)>>1);
// 说明target 在左边
if(target < nums[middle]) r = middle - 1;
// 说明target 在右边
else if(target > nums[middle]) l = middle + 1;
// 说明找到结果
else return true;
}
return false;
}