二分查找是一种在有序数组中查找特定元素的高效算法。在二分查找中,upper_bound、lower_bound 和 binary_search 是三个常用的操作,C++标准库也提供了原生 API,它们都利用了二分查找,但用于解决略微不同的问题。
介绍
binary_search
- 定义:判断一个有序序列中是否存在指定的值。
- 返回值:如果序列中存在该值,返回true;否则,返回false。
用途:仅用于检查序列中是否包含某个特定的值,不提供该值的位置信息。
类似于 LeetCode704.二分查找,但是返回值是 bool 值。
lower_bound
- 定义:在有序数组中找到第一个等于目标值的元素的位置。
- 返回值:如果数组中存在一个或多个目标值,则
lower_bound
返回指向第一个目标值的迭代器。如果所有元素都小于目标值,则返回指向数组末尾的迭代器。 - 用途:
lower_bound
常用于查找数组中第一个等于目标值的元素的位置,或者获取可以插入该值而不破坏数组排序的位置。
upper_bound
- 定义:在一个有序数组中找到第一个大于目标值的元素的位置。
- 返回值:如果数组中存在目标值,则
upper_bound
返回指向第一个大于目标值的元素的迭代器。如果所有元素都不大于目标值则返回指向数组末尾的迭代器。 - 用途:
upper_bound
常用于确定一个范围,特别是当需要找出所有等于目标值的元素的范围时。
示例
假设有一个有序数组 arr = [1, 2, 4, 4, 5, 6 ,7]
,我们需要差中值为 4 的 lower_bound
和 upper_bound
。lower_bound(4)
将返回指向第一个 4 的迭代器,即 arr[2]
。upper_bound(4)
将返回指向 5 的迭代器,即 arr[4]
。
接口
binary_search
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
lower_bound
inline _ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
upper_bound
inline _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
使用
lower_bound和upper_bound它们都接受三个参数:开始迭代器、结束迭代器和目标值。如果需要得到索引,需要使用返回的迭代器和开始迭代器做差来获取。
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> arr = {1, 2, 4, 4, 5, 6, 7};
auto lower = std::lower_bound(arr.begin(), arr.end(), 4);
auto upper = std::upper_bound(arr.begin(), arr.end(), 4);
bool binary = binary_search(arr.begin(), arr.end(), 4);
std::cout << "Lower Bound: " << (lower - arr.begin()) << std::endl;
std::cout << "Upper Bound: " << (upper - arr.begin()) << std::endl;
return 0;
}
upper_bound 和 lower_bound 自定义版本可以查看这篇文章。