文章目录

  • 二分查找的思路
  • 算法复杂度
  • 几种不同的二分查找
    • 1. 普通二分
    • 2. 二分答案
    • 3. 小数二分

二分查找的思路

二分查找也称为折半查找(binary search),适用于顺序存储结构的线性表,且表中元素是有序排列的情况。对于一个顺序排列的数组而言,当查找区间有不止一个元素的时候(即左边界不超过右边界),每次循环取当前区间中间的元素与目标值比较,根据以下三种比较结果判断跳出循环或更新左右边界:

  1. 目标值 = 中间元素
    此时正好在在当前区间的中间找到目标值,跳出循环。
  2. 目标值 > 中间元素
    表示此时目标值在以中间元素为界的右区间,需要移动左边界以在右区间继续进行查找。
  3. 目标值 < 中间元素
    表示此时目标值在以中间元素为界的左区间,需要移动右边界以在左区间继续进行查找。

算法复杂度

由于二分查找的适用场景为顺序表,因此空间复杂度为 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=log2​n因此,二分查找的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2​n)。

几种不同的二分查找

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均为答案,二者任选其一即可。
  • 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均为答案,二者任选其一即可。

3. 小数二分

对于小数二分,推导思路与上述两种问题一样,唯一需要注意的地方是循环的条件发生了变化。因为二分的对象为浮点型数据,查找区间应为开区间而不是闭区间了,所以不需要再判断左右边界是否相等,而是通过判断左右边界之间差值的精度(如r - l > 0.00001),近似的判断左右边界是否重合。

算法基础——关于二分查找的那些事相关推荐

  1. 1.9 编程基础之二分查找 12 最长平台 python

    http://noi.openjudge.cn/ch0109/12/ """1.9 编程基础之二分查找 12 最长平台 http://noi.openjudge.cn/c ...

  2. 1.9 编程基础之二分查找 13:整数去重 python

    http://noi.openjudge.cn/ch0109/13/ """1.9 编程基础之二分查找 13:整数去重 http://noi.openjudge.cn/c ...

  3. 1.11 编程基础之二分查找 08 不重复地输出数 python

    http://noi.openjudge.cn/ch0111/08/ """ 1.11 编程基础之二分查找 08 不重复地输出数 http://noi.openjudge ...

  4. 查找算法之一:二分查找(递归实现)

    二分查找的递归实现 思路分析 代码实现 思路分析 1.确定该序列的中间的下标mid: mid = (left + right)/2: 2.让需要查找的数findVal 与 arr[mid]进行比较: ...

  5. c语言二分法查找一个数_算法简解-二分查找

    读书不记录=没读,始终是我的信条·····最近因为要参加竞赛,发现自己真的差的很远,所以打算重新开始学习一遍算法及AI的相关数学知识,相信很多人都是闻数学,理工科色变,之前也是觉得上数理课太难了,真的 ...

  6. 算法(一):二分查找法

    算法基础: 一.大O表示法: 指示算法的速度有多快,用于指出随数量的增大,算法的所需步骤增加的速度,常见的大O运行时间(时间复杂度): O(1)表示常数阶时间复杂度 O(log n),也叫对数时间复杂 ...

  7. 算法前戏 递归 二分查找 列表查找

    一.递归 概念: 函数直接或者间接的调用自身算法的过程,则该函数称为递归函数.在计算机编写程序中,递归算法对解决一大类问题是十分有效的. 特点: ①递归就是在过程或者函数里调用自身. ②在使用递归策略 ...

  8. java 二分搜索获得大于目标数的第一位_程序员数据结构算法编程,二分查找搜索算法的原理与应用介绍!...

    本文来讲一种搜索算法,即二分搜索算法,通常在面试时也会被问到. 我们先来看一个例子,在图书馆通常是根据查到的编号去找书,可以在书架上按顺序一本本地查找,也可以找到一本书不符合预期时,再跳过一大部分书再 ...

  9. C++算法五:二分查找(折半)查找

    二分查找是对排序的数据进行排序,查找效率非常高. 2的20次方是100万,就是(1M),折半查找100万个数据只需要20次 2的30次方就是10亿,也就是(1G),折半查找只需要30次 #includ ...

最新文章

  1. 实验五 oracle高级数据查询技术
  2. 转载 SharedPreference.Editor的apply和commit方法异同
  3. shell 打印追加_[转]shell 数组定义、使用和追加
  4. SpringBoot+Thymeleaf+DataTables实现数据的查询与显示
  5. Cordova学习--iOS自定义插件
  6. C 语言快速入门,21 个小项目足矣!「不走弯路就是捷径」
  7. javascript --- 抽象相等
  8. 【转】10个让人受益的管理原理
  9. SUSE11 搭建iscsi target 配置
  10. SpringMVC学习(六)处理乱码问题
  11. string中c_str()用法
  12. 基于 NodeJs 打造 Web 在线聊天室
  13. 只要一行代码,批量将Word转换为PDF!
  14. java浅拷贝与深拷贝及拷贝工具推荐
  15. 关于ProcessOn在线做图工具上找不到宋体,黑体字体样式的解答
  16. LibreOJ - 10066 新的开始
  17. 信息安全技术 应用软件安全编程指南
  18. c语言全部题目及答案,C语言全部题目及答案
  19. (七)python网络爬虫(理论+实战)——json数据解析
  20. html5病毒营销,病毒式营销的特点及成功案例

热门文章

  1. 抖音机制有哪些,机制是基础,明白了机制也就懂得了路数
  2. 假期穿上这款超轻亲子鞋,蹦蹦哒哒合家欢丨钛空舱
  3. C#——窗体程序利用委托进行两个数的加减乘除计算的多种方法。(委托的多种使用方法)
  4. 【03 yy and shop】
  5. hpuoj【1040】寻找单身狗 【思维】
  6. 配图讲解10个进阶构图技巧
  7. 20221105新手老手怎么把网站权重提高收录提高最新php轻量级插件网站权重8怎么上去的seo到底怎么做看完本视频你就懂了许多了本插件适合所有网站所有cms长河网zhetiaohe源码无加密
  8. 英语阶段总结—历程回顾
  9. 数据库-SQL语句练手
  10. HDU2060 Snooker斯诺克