二分查找
思路
定义 target
是在一个在左闭右闭的区间里,也就是[left, right]
(这个很重要非常重要)。因为定义target
在[left, right]
区间,所以有如下两点:
while (left <= right)
要使用<=
,因为left == right
是有意义的,所以使用<=
if (nums[middle] > target) right
要赋值为middle - 1
,因为当前这个nums[middle]
一定不是target
,那么接下来要查找的左区间结束下标位置就是middle - 1
。
代码
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right){
int mid=left+right>>1;
if(nums[mid]>target) right=mid-1;
else if (nums[mid]<target) left=mid+1;
else return mid;
}
return -1;
}
题目
- 二分查找:力扣题目链接
两种二分模板
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
浮点二分模板
bool check(double x) {/* ... */} // 检查x是否满足某种性质
double bsearch_3(double l, double r)
{
const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
while (r - l > eps)
{
double mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
return l;
}