算法基础——关于二分查找的那些事
文章目录
- 二分查找的思路
- 算法复杂度
- 几种不同的二分查找
- 1. 普通二分
- 2. 二分答案
- 3. 小数二分
二分查找的思路
二分查找也称为折半查找(binary search)
,适用于顺序存储结构的线性表
,且表中元素是有序排列
的情况。对于一个顺序排列的数组而言,当查找区间有不止一个元素的时候
(即左边界不超过右边界),每次循环取当前区间中间的元素与目标值比较,根据以下三种比较结果判断跳出循环或更新左右边界:
- 目标值 = 中间元素
此时正好在在当前区间的中间找到目标值,跳出循环。 - 目标值 > 中间元素
表示此时目标值在以中间元素为界的右区间,需要移动左边界以在右区间继续进行查找。 - 目标值 < 中间元素
表示此时目标值在以中间元素为界的左区间,需要移动右边界以在左区间继续进行查找。
算法复杂度
由于二分查找的适用场景为顺序表,因此空间复杂度为 O ( 1 ) O(1) O(1)。
假设数组中有n个元素,且为顺序排列,如果进行进行二分查找过程如下:
- Step 1:在长度为n的区间中查找
- Step 2:在长度为 n / 2的区间中查找
- Step 3:在长度为 (n / 2) / 2 的区间中查找
- ……
- Step x:在长度为 n / (2 ^ (x - 1)) 的区间中查找
由此可见,若在最坏情况
下经过x次查找寻找到答案,最终区间长度应为1,即:
n / 2 x − 1 = 1 n / 2^{x - 1} = 1 n/2x−1=1 x = l o g 2 n x = log_2n x=log2n因此,二分查找的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)。
几种不同的二分查找
1. 普通二分
假设一个已经排好序的数组num中有n个元素,t为需要查找的目标值。
int binary_search(int t) {int l = 0, r = n - 1;while (l <= r) {int mid = (l + r) / 2;if (num[mid] == x) {return 1;} else if (x > num[mid]) {l = mid + 1;} else {r = mid - 1;}}return 0;
}
在缩减查找区间
的时候,需要注意的是,每次都略过了mid这个中间元素。这是因为在前面的判断中已经确定了num[mid]不是我们需要的值,所以在下一次循环查找中,不需要将其包含在查找区间中。
2. 二分答案
在实际的问题中,有时二分的对象未必是答案,而是需要将二分的对象经过某些特殊运算得到的值进行判断,由此得到满足条件的解。此类型问题的答案通常具有单调性
,且多数为边界值解(如求最大的最小值等),这类问题被统称为二分答案问题
。
对于二分答案类型问题的思路,可以从二分的对象入手进行推导:
- 首先对于一组样例输入数据,找到符合条件的目标边界值。
- 取该值的相邻值进行判断,如果能满足条件则该侧均能满足条件(1),不满足条件则该侧均不能满足条件(0)。
- 据此可以建立起对应的
代码模型
,根据不同输入样例求解。
因此,二分答案的结果可以近似为两种类型:00001111型和11110000型。
两种类型的代码模版如下:
00001111型
while (l != r) {int mid = (l + r) / 2;if (func(mid) >= t) { // t为目标查找数r = mid;} else {l = mid + 1;} } return r; // return l;
注意:
- 移动右边界时,mid可能正好是答案,在新的查找区间中
需要
包含mid。 - 移动左边界时,经过前面判断可知mid不是答案,所以在新的查找区间中
不需要
包含mid。 - 最终左边界 = 右边界,查找区间不存在,此时l和r均为答案,二者任选其一即可。
- 移动右边界时,mid可能正好是答案,在新的查找区间中
11110000型
while (l != r) {int mid = (l + r + 1) / 2;if (func(mid) <= t) { // t为目标查找数l = mid;} else {r = mid - 1;} } return l; // return r;
注意:
- 在查找区间只剩下两个元素的时候(10),如果仍然使用 m i d = ( l + r ) / 2 mid = (l + r) / 2 mid=(l+r)/2来计算mid, m i d = l mid = l mid=l将会永远成立,查找区间不会缩小,导致
死循环
。所以需要使用 m i d = ( l + r + 1 ) / 2 mid = (l + r + 1) / 2 mid=(l+r+1)/2向上取整来计算mid的值。 - 移动左边界时,mid可能正好是答案,在新的查找区间中
需要
包含mid。 - 移动右边界时,经过前面判断可知mid不是答案,所以在新的查找区间中
不需要
包含mid。 - 最终左边界 = 右边界,查找区间不存在,此时l和r均为答案,二者任选其一即可。
- 在查找区间只剩下两个元素的时候(10),如果仍然使用 m i d = ( l + r ) / 2 mid = (l + r) / 2 mid=(l+r)/2来计算mid, m i d = l mid = l mid=l将会永远成立,查找区间不会缩小,导致
3. 小数二分
对于小数二分,推导思路与上述两种问题一样,唯一需要注意的地方是循环的条件发生了变化。因为二分的对象为浮点型数据
,查找区间应为开区间
而不是闭区间了,所以不需要再判断左右边界是否相等,而是通过判断左右边界之间差值的精度(如r - l > 0.00001),近似的判断左右边界是否重合。
算法基础——关于二分查找的那些事相关推荐
- 1.9 编程基础之二分查找 12 最长平台 python
http://noi.openjudge.cn/ch0109/12/ """1.9 编程基础之二分查找 12 最长平台 http://noi.openjudge.cn/c ...
- 1.9 编程基础之二分查找 13:整数去重 python
http://noi.openjudge.cn/ch0109/13/ """1.9 编程基础之二分查找 13:整数去重 http://noi.openjudge.cn/c ...
- 1.11 编程基础之二分查找 08 不重复地输出数 python
http://noi.openjudge.cn/ch0111/08/ """ 1.11 编程基础之二分查找 08 不重复地输出数 http://noi.openjudge ...
- 查找算法之一:二分查找(递归实现)
二分查找的递归实现 思路分析 代码实现 思路分析 1.确定该序列的中间的下标mid: mid = (left + right)/2: 2.让需要查找的数findVal 与 arr[mid]进行比较: ...
- c语言二分法查找一个数_算法简解-二分查找
读书不记录=没读,始终是我的信条·····最近因为要参加竞赛,发现自己真的差的很远,所以打算重新开始学习一遍算法及AI的相关数学知识,相信很多人都是闻数学,理工科色变,之前也是觉得上数理课太难了,真的 ...
- 算法(一):二分查找法
算法基础: 一.大O表示法: 指示算法的速度有多快,用于指出随数量的增大,算法的所需步骤增加的速度,常见的大O运行时间(时间复杂度): O(1)表示常数阶时间复杂度 O(log n),也叫对数时间复杂 ...
- 算法前戏 递归 二分查找 列表查找
一.递归 概念: 函数直接或者间接的调用自身算法的过程,则该函数称为递归函数.在计算机编写程序中,递归算法对解决一大类问题是十分有效的. 特点: ①递归就是在过程或者函数里调用自身. ②在使用递归策略 ...
- java 二分搜索获得大于目标数的第一位_程序员数据结构算法编程,二分查找搜索算法的原理与应用介绍!...
本文来讲一种搜索算法,即二分搜索算法,通常在面试时也会被问到. 我们先来看一个例子,在图书馆通常是根据查到的编号去找书,可以在书架上按顺序一本本地查找,也可以找到一本书不符合预期时,再跳过一大部分书再 ...
- C++算法五:二分查找(折半)查找
二分查找是对排序的数据进行排序,查找效率非常高. 2的20次方是100万,就是(1M),折半查找100万个数据只需要20次 2的30次方就是10亿,也就是(1G),折半查找只需要30次 #includ ...
最新文章
- 实验五 oracle高级数据查询技术
- 转载 SharedPreference.Editor的apply和commit方法异同
- shell 打印追加_[转]shell 数组定义、使用和追加
- SpringBoot+Thymeleaf+DataTables实现数据的查询与显示
- Cordova学习--iOS自定义插件
- C 语言快速入门,21 个小项目足矣!「不走弯路就是捷径」
- javascript --- 抽象相等
- 【转】10个让人受益的管理原理
- SUSE11 搭建iscsi target 配置
- SpringMVC学习(六)处理乱码问题
- string中c_str()用法
- 基于 NodeJs 打造 Web 在线聊天室
- 只要一行代码,批量将Word转换为PDF!
- java浅拷贝与深拷贝及拷贝工具推荐
- 关于ProcessOn在线做图工具上找不到宋体,黑体字体样式的解答
- LibreOJ - 10066 新的开始
- 信息安全技术 应用软件安全编程指南
- c语言全部题目及答案,C语言全部题目及答案
- (七)python网络爬虫(理论+实战)——json数据解析
- html5病毒营销,病毒式营销的特点及成功案例