二分查找算法模版

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、什么是二分查找?

二分查找(Binary Search)是一种在有序数组中高效查找特定元素的算法,也称为折半查找。其核心思想是通过不断将搜索区间缩小一半,直到找到目标元素或确定目标不存在,时间复杂度为 O(log n)。

二、二分查找如何写

二分查找看似简单,有时候怎么写都可以,有时候怎么写都写不对,那么今天给大家介绍两个二分查找的算法模版,可以解决学习二分查找中遇到的大部分问题。

1.查找大于等于x的最小值(x 的前驱)

适用场景:在单调递增序列中,找到第一个大于或等于目标值 x 的元素。若 x 存在于序列中,返回 x 本身;若不存在,返回比 x 大的最小元素。
代码如下(示例):

while(l < r)
{
    int mid = (l + r) / 2;
    if(a[mid] >= x)	r = mid;
    else	l = mid + 1;
}

核心逻辑解析:

  • 初始区间为 [l, r](通常 l=0,r = 数组长度 - 1)。
  • 每次通过 a[mid] 与 target 的比较,将区间收缩为 [l, mid] 或 [mid+1, r],确保答案始终在区间内。
  • 由于 mid 向下取整,当区间长度为 2 时(如 l=2,r=3),mid=2,避免收缩后跳过可能的答案。

2.查找小于等于x的最大值(x 的后继)

适用场景:在单调递增序列中,找到最后一个小于或等于目标值 x 的元素。若 x 存在于序列中,返回 x 本身;若不存在,返回比 x 小的最大元素。

代码如下(示例):

while(l < r)
{
    int mid = (l + r + 1) / 2;
    if(a[mid] <= x)	l = mid;
    else	r = mid - 1;
}

核心逻辑解析:

  • 初始区间同样为 [l, r]。
  • 每次通过 a[mid] 与 target 的比较,将区间收缩为 [mid, r] 或 [l, mid-1],确保答案始终在区间内。
  • 由于 mid 向上取整(加 1 后再除以 2),当区间长度为 2 时(如 l=2,r=3),mid=3,避免收缩后左边界无法推进(若用普通取整,可能导致 l 始终 = 2,陷入死循环)。

三、注意事项

  1. 前提条件:数组必须是单调递增的,若为单调递减序列,需调整比较逻辑(如将 >= 改为 <=)。
  2. 边界初始化:通常初始 l=0,r=数组长度-1,但需根据具体问题调整(如处理空数组时需提前判断)。
  3. 结果验证:循环结束后,需根据题意验证 a[l] 是否符合条件(例如,若所有元素都大于 x,查找前驱时结果可能不符合预期,需额外处理)。
  4. 死循环避免:
    • 查找后继时,mid 必须向下取整,否则可能因右边界收缩过慢导致死循环。
    • 查找前驱时,mid 必须向上取整,否则可能因左边界无法推进导致死循环。

总结

二分查找的核心是区间收缩逻辑和中间值取法,上述两个模板通过固定的取整方式和收缩规则,解决了大部分边界问题:

  • 查找 “大于等于 x 的最小值” 用 mid = (l + r) / 2,收缩规则为 >=则右边界左移,否则左边界右移。
  • 查找 “小于等于 x 的最大值” 用 mid = (l + r + 1) / 2,收缩规则为 <=则左边界右移,否则右边界左移。

掌握这两个模板后,可举一反三解决二分查找的各类变体问题,如在重复元素中查找特定位置、求解满足条件的最值等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值