数据结构与算法——二分
最近leetcode每日一题经常出二分的题目,正好对前段时间学过的二分进行一些总结,首先这里要明确的一点是,二分的本质并不是单调性,而是通过某种条件将整个区间划分成满足条件和不满足条件的两端即可进行二分查找。
在二分这个专题,主要有两种类型的划分方式,一种是整数划分,一种是浮点数划分,前一种一般是我们最熟悉的二分查找的题型,也是出题比较灵活考的比较多的一种,后一种主要是为控制实数精度而设置的浮点数二分法(建议用double
,float
有时候会出现精度丢失)。
整数二分
这里我们拿一道经典例题来给出我们二分的两个十分精妙的模板。AcWing789. 数的范围
|
浮点数二分
浮点数二分考的比较少,主要是实现对于高精度答案的控制。AcWing 790. 数的三次方根
这里有个小bug需要提醒一下,我们以求二次方根为例,我们可以知道,$x=0.01$时,$\sqrt{x}=0.1>x$,所以当我们把二分的区间设置成$[0,x]$时,我们则无法找到答案,所以设置区间的时候我们最好可以设置大一点的区间,或者设置成$[0,\max(1,x)]$
|
STL
做题当中手写二分的题其实比较少,基本上记忆上述模板就能解决所以的问题,同时我们在日常做题的时候,为了方便,我们通常是使用STL当中的函数来实现二分,且支持vector,map,set等操作,还有结构体大小比较,这里就有三个一定要记住的API。头文件引入:#include<algorithm>
binary_search
功能:二分查找某个元素是否出现。
返回值:在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则真,若查找不到则返回值为假。
用法实例:
a.数组用法
|
b.vector用法
|
lower_bound
功能:查找非递减序列[first,last) 内第一个大于或等于某个元素的位置。
返回值:如果找到返回找到元素的地址否则返回数组边界的下一个元素的地址。(这样不注意的话会越界,小心)
用法实例:
|
b.vector用法
|
upper_bound
功能:查找非递减序列[first,last) 内第一个大于某个元素的位置。
返回值:如果找到返回找到元素的地址,否则返回数组边界的下一个元素的地址。(同样这样不注意的话会越界,小心)
用法实例:
|
b.vector用法
|
经典例题
这里我顺便给出这两天的每日一题的解题方案,里面还涉及到了一个防止溢出的二分处理trick。
猜数字大小
|
|
这是三叶姐姐的二分经典题型汇总,大家也可以参考一下。