二分查找与三分查找
二分查找
概念
- 二分查找又叫折半查找,利用单调序列的单调性,每次将范围缩小一般,在大规模查找数据的时候有显著优势。
- 优点:
- 普通查找的时间复杂度为O(n),而二分查找的时间复杂度为O(log n),也就是说百万级别的数据只需要几十次查找就能确定。
- 在答案的穷举里面有很大的优势,因此引出了
二分答案这个概念
- 缺点:
- 二分查找只能找具有单调性的序列,对于混乱的数据是没办法查找的
代码实现及注意事项
- 代码实现:
1 | |
解释: 这里面我们查找的是符合答案的序号最小值,当有符合的答案的时候,我们的right会往左边收缩,也就是right是尝试值,left为确定值,result是来确定是否有答案的,最后left的值和result的值理论上是一样的。
- 注意事项: 我们这个模板采用了两边都是闭区间的情况,当
right==left的时候,mid=right=left这是侯mid是合法区间,因此我们要查找这种情况,因此在对while的条件书写的时候,我们是left<=right而不是left<right - 我们要对
a[mid]==k的情况进行判断,我们这个模板是找最小序号,如果想找最大序号,我们就要把mid部分放到else里面,把条件改为a[mid]>k 习题:这里推荐洛谷题单 跳转链接
二分答案
- 概念: 就是对答案进行二分查找
- 使用条件: 二分答案的前提是条件的答案具有单调性,同时我们条件具有范围
- 在洛谷题单里面就有对应的题
三分查找
概念
三分查找是一种用于在单峰函数(先严格递增后严格递减,或先严格递减后严格递增)中寻找极值点的高效算法。
与二分查找每次将区间分为两部分不同,三分查找每次将区间分为三部分,通过比较两个中间点的函数值来缩小搜索范围。
核心思想
对于单峰函数,极值点(最大值或最小值)可以通过不断缩小搜索区间来定位
每次迭代选取两个中间点,根据这两个点的函数值关系,可以确定极值点位于哪个子区间
算法流程
确定初始区间
[left, right]当区间长度足够大时循环:
计算两个中间点:
mid1 = left + (right - left) / 3mid2 = right - (right - left) / 3
比较
f(mid1)和f(mid2):如果寻找最小值:
若
f(mid1) < f(mid2),则极值点在[left, mid2]若
f(mid1) > f(mid2),则极值点在[mid1, right]若相等,极值点在
[mid1, mid2]
如果寻找最大值:
若
f(mid1) > f(mid2),则极值点在[left, mid2]若
f(mid1) < f(mid2),则极值点在[mid1, right]若相等,极值点在
[mid1, mid2]
代码实现
1 | |
整数版本的三分查找
1 | |
时间复杂度
时间复杂度:O(log₃n),其中n为初始区间长度
每次迭代将搜索区间缩小为原来的2/3
虽然底数不同,但时间复杂度仍为对数级别
应用场景
二次函数极值:抛物线等单峰函数的极值点查找
几何问题:点到曲线的最短距离
优化问题:在满足单峰性质的函数中寻找最优解
物理问题:光的折射路径、最短时间问题等
与二分查找的对比
| 特性 | 二分查找 | 三分查找 |
|---|---|---|
| 适用条件 | 单调序列 | 单峰函数 |
| 每次比较 | 1次 | 2次 |
| 区间缩小 | 1/2 | 2/3 |
| 时间复杂度 | O(log₂n) | O(log₃n) |
注意事项
单峰性验证:使用前必须确认函数在搜索区间内是单峰的
精度控制:浮点数版本需要设置合适的精度阈值
边界处理:整数版本在区间较小时需要转为线性搜索
函数计算:每次迭代需要计算两次函数值,确保函数计算不耗时
习题推荐
洛谷 P3382 【模板】三分法
抛物线最小距离问题
物理中的最优化问题
三分查找是解决单峰函数极值问题的有力工具,在竞赛和实际问题中都有广泛应用。


