尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

二分查找本质

二分查找本质
📅 发布时间:2026/6/28 18:16:44

二分查找本质

二分查找

说到二分查找,对于稍微了解过经典算法的计算机学生来说,简直太熟悉不过。能够将线性查找时间复杂度O(N)缩为O(logN)。但很多时候,理解二分思想,和能够在正确的场景正确的位置上使用二分之间还是有段距离了,这里面需要有对于二分算法的本质理解。

defbinary_search(nums,target):left,right=0,len(nums)-1whileleft<=right:mid=(left+right)//2ifnums[mid]==target:returnmid# 找到直接返回elifnums[mid]<target:left=mid+1else:right=mid-1return-1

二分本质

二分查找为什么能够将线性查找时间复杂度O(N)缩为O(logN)?普通查找遍历一个数组,需要从头到尾挨个遍历判断,而二分查找,每次取中点元素进行判断,满足与不满足条件,都能砍掉一半待判断元素。
“砍掉一半待判断元素”就是二分的本质。为了能砍掉一半待判断元素,二分查找的应用才需要数组的“有序”属性,这个“有序”属性,可以是直观上的有顺序,例如待遍历元素值递增、递减顺序等,也可以是逻辑上的有顺序,待求的目标值,在遍历的过程中是有顺序的。
结合实际例子来讲,最简单的,给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果 target 存在返回下标,否则返回 -1。

输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在 nums 中并且下标为4

正常去挨个遍历,时间复杂度为O(N),而使用二分,每次先取中点位置元素,进行条件校验(这里是判断中点元素mid与目标值target的大小关系),若等于,则直接返回,若比较大了,由于序数组升序,则mid右侧那一半元素肯定更大,直接砍掉,待遍历区间少一半;若比较小了,由于序数组升序,则mid左侧那一半元素肯定更小,直接砍掉,待遍历区间少一半。这里的本质很好找,直接观察元素值大小即可。
再来一个例子,给你两个正整数数组 spells 和 potions ,长度分别为 n 和 m ,其中 spells[i] 表示第 i 个咒语的能量强度,potions[j] 表示第 j 瓶药水的能量强度。同时给你一个整数 success 。一个咒语和药水的能量强度 相乘 如果 大于等于 success ,那么它们视为一对 成功 的组合。请你返回一个长度为 n 的整数数组 pairs,其中 pairs[i] 是能跟第 i 个咒语成功组合的 药水 数目。

输入:spells=[3,1,2],potions=[8,5,8],success=16输出:[2,0,2]解释:-第0个咒语:3*[8,5,8]=[24,15,24]。总共2个成功组合。-第1个咒语:1*[8,5,8]=[8,5,8]。总共0个成功组合。-第2个咒语:2*[8,5,8]=[16,10,16]。总共2个成功组合。 所以返回[2,0,2]。

正常思路就是挨个遍历spells元素spells[i],再挨个遍历potions元素potions[j],判断spells[i]*potions[j] >= success,若大于,则res[i]++,此时时间复杂度O(N²)。但是我们可以想一想,假如让spells或者potions升序(为了让结果数据res更好赋值,这里假设让potions升序),那么只要spells[i]*potions[j]与success的大小关系判断出来了,例如spells[i]*potions[j] >= success,那么由于升序关系,spells[i]*potions[j...n-1]即spells[i]*potions[j]右边的任一元素都会更大,肯定同样满足条件,那么直接累计答案个数,无需再遍历potions的下标j - n-1,即砍掉了一半的待遍历元素。
我们只需要二分找到第一个potions[j],满足spells[i]*potions[j] >= success即可,外层依旧是挨个遍历spells元素,时间复杂度O(NlogN)。
值得一提的是,二分找到第一个目标元素(数组元素不要求重复),和二分查找目标元素的写法有一点区别,这里还是以左闭右毕为例:

# 找第一个大于等于 target 的下标deflower_bound(nums,target):left=0right=len(nums)-1res=len(nums)# 兜底:全部元素都小于target,返回数组长度whileleft<=right:mid=(left+right)//2ifnums[mid]>=target:# 当前mid符合条件,先记下来,去左边找更小下标res=mid right=mid-1else:# 当前太小,左边全部作废,往右找left=mid+1returnres

当然,以上只是两个最简单的题目例子,大多数时候,实际的算法题目不会将要二分的“对象”暴露的这么明显(例如最大化最小值、最小化最大值等),但是本质一定还是:通过一个代表元素的条件判断,代替一半区间元素条件判断,砍掉一半待遍历元素。

相关新闻

  • Flashtool完整指南:掌握索尼Xperia设备刷机与固件管理的实用工具
  • IntelliJ插件生态崩塌预警?2024 JetBrains官方未公开的6个内置替代方案已上线
  • 如何在Mac上制作Windows启动盘:WinDiskWriter完整使用指南

最新新闻

  • Burp Suite入门指南:从零掌握Web安全测试核心工具
  • 【UEFI实战】EDK2编译环境搭建与OVMF构建全攻略
  • [矩阵论]Hamilton-Cayley定理:从特征多项式到矩阵幂的降维钥匙
  • 082、案例二:React 组件库的 AI 辅助开发与文档自动生成
  • CAD Assistant:解锁多源3D数据互通的工程实践
  • 从ROUGE到BLEU:解码文本生成评估指标的核心逻辑与应用实战

日新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号