有序数组二分查找模板
Posted 清水寺扫地僧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有序数组二分查找模板相关的知识,希望对你有一定的参考价值。
文章目录
二分查找基础
二分本质上是对边界进行二分,将查找范围缩小为原先的一半。
查找有序数组中,会有如下相关的子问题可以运用二分进行解决:
- ① 查找某一个数;
- ② 最后一个小于目标值target的数;
- ③ 最后一个小于等于目标值target的数;
- ④ 第一个大于目标值target的数;
- ⑤ 第一个大于等于目标值target的数;
采用二分查找,返回该数的索引,没有的话返回-10(non_exit) ;
int mid = (l + r) / 2
和 int mid=l+(r-l)/2;
的区别在于:
int mid = (l + r) / 2
中 (l + r)
可能出现整数溢出,这就导致计算结果不是正确的中位数。
① 查找某一个数
//二分查找某个数
int binarySearchOne(vector<int> vec, int target) {
int l = 0, r = vec.size() - 1;
while (l <= r) {
int mid=l+(r-l)/2;
if (vec[mid] == target) //关键点
return mid;
if (vec[mid] > target) r = mid - 1;
else l = mid + 1;
}
return non_exit;
}
② 最后的小于目标值target的数
//二分查找最后一个小于某个数
int binarySearchFirstLess(vector<int> vec, int target) {
int l = 0, r = vec.size() - 1;
while (l <= r) {
int mid = l+(r-l)/2;
//关键点,>=
if (vec[mid] >= target) r = mid - 1;
else l = mid + 1;
}
//区分索引越界,即没找到
if(r<0) return non_exit;
return r;
}
③ 最后的小于等于目标值target的数,即右边界
//二分查找最后一个小于等于某个数,若相等则返回最右边的
int binarySearchFirstLessEqual(vector<int> vec, int target) {
int l = 0, r = vec.size() - 1;
while (l <= r) {
int mid = l+(r-l)/2;
//关键点,>
if (vec[mid] > target) r = mid - 1;
else l = mid + 1;
}
//如果要找的是最后一个等于target的位置,则条件是 if(r<0 || vec[r]!=target)
if (r < 0) return non_exit;
return r;
}
分析:
- 对于题目②小于、题目③小于等于,代码不同的在于关键点处:
题目②小于:则将大于等于分为一类;
题目③小于等于:则将大于分为一类; - 最后返回,也即对应了题设中"最后的";
④ 第一个大于目标值target的数
//二分查找第一个大于某个数
int binarySearchFirstGreater(vector<int> vec, int target) {
int l = 0, r = vec.size() - 1;
while (l <= r){
int mid = l+(r-l)/2;
//关键点,<=
if (vec[mid] <= target) l = mid + 1;
else r = mid - 1;
}
//区分索引越界,即没找到
if (l >= vec.size()) return non_exit;
return l;
}
⑤ 第一个大于等于目标值target的数,即左边界
//二分查找第一个大于等于某个数,若相等则返回最左边的
int binarySearchFirstGreaterEqual(vector<int> vec, int target) {
int l = 0, r = vec.size() - 1;
while (l <= r) {
int mid = l+(r-l)/2;
//关键点,<
if (vec[mid] < target) l = mid + 1;
else r = mid - 1;
}
//如果要找的是第一个等于target的位置,则条件是 if(l >= vec.size() || vec[l]!=target)
if (l >= vec.size()) return non_exit;
return l;
}
分析:
- 对于题目④大于、题目⑤大于等于,代码不同的在于关键点处:
题目④大于:则将小于等于分为一类;
题目⑤大于等于:则将小于分为一类; - 最后返回 l,也即对应了题设中"第一个";
以上是关于有序数组二分查找模板的主要内容,如果未能解决你的问题,请参考以下文章
算法二分法 ② ( 排序数组中查找目标值 | 二分法的经典写法 | 在排序数组中查找元素的最后一个位置 | 二分法的通用模板 )