二分查找和二分答案模板
1、二分查找
关于二分查找主要有三种模板
模板1 结束条件为 l + 1 == r
查找最后一个 <= x
数的下标 (最大化查找,可行区在左侧)
int find(int x) { int l = 0,r = n + 1; // 开区间,数据存储下标为1~n while(l + 1 < r) { int mid = l + r >> 1; if(a[mid] <= x) l = mid; else r = mid; } return l; }
查找第一个 >= x
数的下标 (最小化查找,可行区在右侧)
int find(int x) { int l = 0,r = n + 1; // 开区间,数据存储下标为1~n while(l + 1 < r) { int mid = l + r >> 1; if(a[mid] >= x) r = mid; else l = mid; } return r; }
模板2 结束条件为 l == r (y总的板子)
查找最后一个 <= x
数的下标 (最大化查找,可行区在左侧)
int find(int x) { int l = 1,r = n; // 闭区间,数据存储下标为1~n while(l < r) { int mid = l + r + 1 >> 1; if(a[mid] <= x) l = mid; else r = mid - 1; } return l; }
查找第一个 >= x
数的下标 (最小化查找,可行区在右侧)
int find(int x) { int l = 1,r = n; // 闭区间,数据存储下标为1~n while(l < r) { int mid = l + r >> 1; if(a[mid] >= x) r = mid; else l = mid + 1; } return r; }
模板3 结束条件为 l == r +1(一个OI同学常用的板子)
查找最后一个 <= x
数的下标 (最大化查找,可行区在左侧)
int find(int x) { int ans = 0; int l = 1,r = n; // 闭区间,数据存储下标为1~n while(l <= r) { int mid = l + r >> 1; if(a[mid] <= x) ans = mid,l = mid + 1; else r = mid - 1; } return ans; }
查找第一个 >= x
数的下标 (最小化查找,可行区在右侧)
int find(int x) { int ans = 0; int l = 1,r = n; // 闭区间,数据存储下标为1~n while(l <= r) { int mid = l + r >> 1; if(a[mid] >= x) ans = mid,r = mid - 1; else l = mid + 1; } return r; }
上面三个板子中比较好用的是第一个和第三个,第二个板子在 >= x
和 <= x
的mid计算方式不同,所以在编程过程中出错的概率更大。
其中第一个板子 和 都只在各自的可行区移动,也就是说在 <= x
的情况下,下标对应的数 一直 <= x
, 下标对应的数一直 > x
我个人比较喜欢第一个板子,接下来用第一个板子介绍一下浮点二分和二分答案。
浮点二分
double find(double x) { double l = 下界 - 1,r = 上界 + 1;//因为是浮点数,这里l,r不那么精确也行,可以适当扩大范围 while(r - l > 1e-5) //因为计算机的精度问题,所以两个浮点数相差1e-5就可以认为是相等的 { double mid = (l + r) / 2; if(check(mid)) l = mid; else r = mid; } return l; }
2、二分答案
2.1 最大化答案(可行区在左侧)
int find() { int l = 下界 - 1,r = 上界 + 1; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) l = mid; else r = mid; } return l; }
2.2 最小化答案(可行区在右侧)
int find() { int l = 下界 - 1,r = 上界 + 1; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid; } return r; }
bool check(int x) { //根据可行区不同,编写不同的check函数 }
本文作者:Sunny不要停
本文链接:https://www.cnblogs.com/mrneojeep/p/17390305.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步