一. 二分查找
1.1 二分查找
- 前提:容器是有序的
- 思路:在容器有序的情况下(如果题目无序,可以自行排序,一般在整体算法为O(nlogn)的情况下都会有自己排序这一步)
以下步骤以区间左闭右闭为例:- 将[l, r]的中点定义为变量
mid = l + (r - l) >> 1
,此处是为了防止溢出 - 比较
arr[mid]
与target
处的值- 若
arr[mid] < target
则将区间往右压缩(即l = mid + 1
) - 若
arr[mid] > target
则将区间往右压缩(即r = mid - 1
)
- 若
- 循环以上步骤,直至
arr[mid] == target
(找到)或l > r
(未找到)
- 将[l, r]的中点定义为变量
- 代码模板(以左闭右闭为例)
- 盘古开天辟地原始版
int binarySearch(int digit[], int target)
{
int l = 0;
int r = N - 1;
while(l <= r)
{
int mid = l + ((r - l) >> 1);//防止内存溢出
if(a[mid] < target)
l = mid + 1;
else if(a[mid] > target)
r = mid - 1;
else
return mid;
}
return -1;//没有
}
下列算法借鉴网友的思想,还有别的求法,不再陈列
下列算法A-B数对部分解法https://www.luogu.com.cn/problem/P1102
,为比较经典的二分查找算法的扩展
- 查找第一次出现的元素
思路:将arr[mid] == target
也算在arr[mid] > target
的情况下,往左收缩区间
int find_first(int t)
{
//左闭右闭
int l = t;
int r = N - 1;
int ans = 0;
while(l < r)//让l==r作为循环退出条件
{
int mid = l + ((r - l) >> 1);
if(num[mid] >= t)
r = mid;
//查找最后一次出现则将区间向右收缩
else
l = mid + 1;
}
if(num[l] == t)
return l;
return -1;//没有
}
- 查找最后一次出现的元素
int find_last(int t)
{
//左闭右闭
int l = t;
int r = N - 1;
int ans = 0;
while(l < r)
{
int mid = l + ((r - l) >> 1);
//查找最后一次出现则将区间向右收缩
if(num[mid] <= t)
l = mid;
else
r = mid - 1;
if(num[l] == t)
return l;
return -1;//没有
}
二. 二分答案
长按点赞可加速显示这部分内容(doge)…