c++表中库函数
std::lower_bound(x) //返回第一个>=x的元素迭代器
std::upper_bound(x) //返回第一个>x的元素的迭代器
注意:查找的返回值为迭代器,查找失败返回末尾元素的后一个位置
ex:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> a = {1,2,3,4,5,6,7,8,9,10};
if(lower_bound(a.begin(),a.end(),0)!=a.end()){
cout << "yes" <<endl;
}
return 0;
}
二分查找算法的实现
B站一篇非常棒的讲解,视频链接:二分查找为什么总是写错?
代码模板:
//搜索区间为[0,N - 1]
int l = -1, r = N;
while(l + 1 != r) {
int mid = l + r >> 1; //(l + r) / 2 向下取整
if(check(mid)) l = mid;
else r = mid;
}
return l or r; //根据需要选择返回的值
简单理解,最开始左指针指向索引为-1(第一个元素的前一个位置),右指针指向最后一个元素的后一个位置,算法执行完后左指针和右指针紧挨着,将数组分成两部分,l指向左边部分的最后一个元素,r指向右边部分的第一个元素,通过设定check条件和返回左指针or右指针,得到你想要的结果。具体看下图。
以找到第一个>=5的元素为例
//搜索区间为[0,N - 1]
int l = -1, r = N;
while(l + 1 != r) {
int mid = l + r >> 1; //(l + r) / 2 向下取整
if(nums[mid] < 5) l = mid;
else r = mid;
}
return r;
练习题
Leetcode 278. 第一个错误的版本
Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
Leetcode 35. 搜索插入位置
class Solution {
public:
int firstBadVersion(int n) {
long long l = -1, r = 1ll + n;
while(r - l > 1) {
long long mid = r + l >> 1;
if(isBadVersion(mid)) r = mid;
else l = mid;
}
return r;
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans;
bool t = false;
long long l = -1, r = nums.size();
while (r - l > 1) {
long long mid = l + r >> 1;
if(nums[mid] == target) t = true;
if (nums[mid] >= target) r = mid;
else l = mid;
}
if(!t) return {-1,-1};
ans.push_back(r);
l = - 1, r = nums.size();
while(r - l > 1) {
long long mid = l + r >> 1;
if(nums[mid] <= target) l = mid;
else r = mid;
}
ans.push_back(l);
return ans;
}
};
//Leetcode34 官方题解 时间100%代码
class Solution
{
public:
int binarySearch(vector<int>& nums, int target, bool lower)
{
int left = 0,
right = (int)nums.size() - 1,
ans = (int)nums.size();
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target || (lower && nums[mid] >= target)) {
right = mid - 1;
ans = mid;
}
else
{
left = mid + 1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target)
{
int leftIdx = binarySearch(nums, target, true);
int rightIdx = binarySearch(nums, target, false) - 1;
if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target)
{
return vector<int>{leftIdx, rightIdx};
}
return vector<int>{-1, -1};
}
};