别乱用二分查找!这些前提条件你都搞清楚了吗?

什么是"二分查找"?一句话

就是每次从中间砍一半,看看目标在左边还是右边,一步步缩小范围,直到找到或者没找到。

看起来高效又帅气,但它不是万能的。它有几个硬性要求,满足了才有用。


前提一:必须是排好序的数据

这是第一大铁律。不排序?别用。

举个例子:

你去图书馆找《西游记》:

  • 如果书按书名从A到Z排好,你翻到中间一看:"射雕英雄传",比"西游记"靠前,继续翻后半部分,很快找到了。
  • 如果图书馆管理员摆书像堆衣服一样乱,那就别想二分查找了,只能一摞一摞翻。

再比如:

你有一堆苹果,每个上面写着价格,你想快速找到"价格是5元的苹果"在哪。

  • 如果这些苹果已经按价格从低到高排好了,二分查找就派上用场;
  • 如果是杂乱地堆一堆,你只能一个个看。

所以,二分查找就是为有序数据准备的VIP通道,乱的别挤。


前提二:得能比大小

说白了,你要能判断目标值和中间值之间的"关系":到底是大了?小了?还是刚刚好?

举个例子:

你猜同学心里想的数字(1~100):

  • 你每次猜一个,他说"太小"或"太大";
  • 你就能往正确方向收缩;
  • 这就能用二分查找。

但如果你在猜"今天班里谁最开心",这个就很尴尬了:

  • 你问一个人:"你是不是最开心的?"
  • 他回答"也许吧"
  • 然后你问下一个,也说"也许吧"......

你根本没法比较大小,那就没法二分。


前提三:数据结构支持随机访问中间

啥意思?你要能很快拿到中间那一项,不能一点点走过去。

举个例子:

  • 如果你手上是一摞纸质的小说书,你能一翻就翻到中间那一章。
  • 但如果你看的是那种一页页滑的手机小说 App,翻中间要滑很久,那效率就低了。

或者说:

  • 数组(Array)支持按下标直接拿,比如 arr[mid]
  • 链表(LinkedList)就不行,得从头往后走,慢得很,不适合二分查找。

前提四:最好是查"具体值"

你要查的目标,是"有没有42""在哪个位置""第一次出现在哪"等明确的问题。

如果你问的是:

  • "大于42的数有哪些?"
  • "哪个数最接近目标?"

这些模糊问题不是不能用二分,但就需要用变种的版本,得多写几行代码,逻辑也会稍微复杂点。


简单小结一下:

适合用二分查找的场景:

场景 为什么可以用?
查字典里的单词 单词是按字母排序的,可以比大小
猜一个 1~100 的数字 数字有序,能说"太大/太小"
找排好序的快递编号 快递单号升序排序,可以比
找超市价格最低的商品(排好序) 有序+能比较+能跳到中间
网上查一个按时间排序的日志 日志时间排序,可以比大小
相关推荐
君爱学习34 分钟前
RocketMQ延迟消息是如何实现的?
后端
Falling421 小时前
使用 CNB 构建并部署maven项目
后端
程序员小假1 小时前
我们来讲一讲 ConcurrentHashMap
后端
爱上语文1 小时前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端
萧曵 丶1 小时前
Rust 中的返回类型
开发语言·后端·rust
高兴达2 小时前
Spring boot入门工程
java·spring boot·后端
到账一个亿4 小时前
后端树形结构
后端
武子康4 小时前
大数据-31 ZooKeeper 内部原理 Leader选举 ZAB协议
大数据·后端·zookeeper
我是哪吒4 小时前
分布式微服务系统架构第155集:JavaPlus技术文档平台日更-Java线程池实现原理
后端·面试·github