二分查找–stl中的妙用
这里主要是将在我们需要用到二分查找的时候,我们不一定要手写二分(但原理一定要明白),原因我们常常会因为区间的问题而出错,而浪费掉很多时间,所以这里整理两个基于二分很好用的stl中的函数。首先需要知道他们都是定义在algorithm的函数.
lower_bound
它的作用是对于从小到大数组,在区间[begin, end)中,返回第一个大于等于value的地址,若找不到,则返回end的地址(这里需要注意的是end不是指数组的最后一个元素,而是数组中最后一个的元素的后一个元素)。
int *p = lower_bound(a.begin(), a.end(), value); // 因为返回的是一个地址,我们用指针变量来接收它
int index = lower_bound(a.begin(), a.end(), value) - a.begin(); // 当我们需要查找value的下标的时候
upper_bound
它的作用是对于从小到大数组,在区间[begin, end)中,返回第一个大于value的地址,若找不到,则返回end的地址。
int index = upper_bound(a.begin(), a.end(), value) - a.begin();
那如果我们要找到value的前一个数,即最后一个小于value的值呢?
这时可以用prev了
prev
“prev”的原意表示前一个,但其功能不只是可以获取前一个地址,也可获取一个与迭代器距离为n的迭代器
vector<int> a{1, 2, 7, 8, 10, 110};
auto it = prev(lower_bound(a.begin(), a.end(), 10)); // 查找元素10的前一个元素地址
cout<<*it<<"\n"; // 8
cout<<it-a.begin(); // 输出8的下标为3
// 当然我们也可以获取一个与迭代器距离为n的迭代器
auto it = prev(a.end(), 2);
cout<<*it<<"\n"; // 输出10
auto it = prev(lower_bound(a.begin(), a.end(), 10), 3);
cout<<*it; // 输出2
因为这个功能,所以prev经常与lower_bound进行连用,在一些二分的题目经常出现。
之前知道有这些函数,但总是偷懒没有整理出来,现在终于整理了一下了 😁