二分法(Binary Search)

目录

一、基本思想

二、二分法的典型应用

1. 有序数组查找

2. 数学求根问题

三、时间复杂度与复杂度分析

四、优缺点

五、常见变体与注意事项

六、应用场景


二分法(Binary Search)是一种高效的查找和逼近算法,核心思想是通过不断将问题规模对半分,缩小搜索范围,直到找到目标值或满足条件的结果。它广泛应用于有序数组查找、方程求根、最优化问题等场景。

一、基本思想

  1. 分治策略:将原问题分解为规模更小的子问题,每次排除一半不可能的解。
  2. 有序性前提:数据必须有序(如升序或降序),这是二分法高效的关键。
  3. 逐步逼近:通过比较中间值与目标值的关系,确定下一步搜索的区间。

二、二分法的典型应用

1. 有序数组查找

场景:在有序数组中快速找到目标值的位置。
步骤

1.初始化左右指针

left=0, right=len(arr)-1

2.计算中间索引(避免整数溢出)

mid = left + (right - left) // 2

3.比较 中间值arr[mid] 与目标值 target

  • 若 arr[mid] == target,返回 mid
  • 若 arr[mid] < target,说明目标在右半区,更新 left = mid + 1
  • 若 arr[mid] > target,说明目标在左半区,更新 right = mid - 1

4.重复直到 left > right,未找到则返回 -1

代码示例:

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

2. 数学求根问题

场景:求解连续函数 f(x)=0 的近似根(如 f(x)=x^3 - x - 2)。
前提:函数在区间 [a, b] 内连续,且 f(a) 和 f(b) 异号(由介值定理保证存在根)。
步骤

1.初始化区间 [a, b],确保 f(a) * f(b) < 0

2.计算中点 c = (a + b) / 2

3.判断 f(c) 的符号:

  • 若 f(c) == 0 或达到精度要求,返回 c
  • 若 f(c) * f(a) < 0,根在 [a, c],更新 b = c
  • 否则根在 [c, b],更新 a = c

4.重复直到区间长度小于预设精度(如 1e-6)。

代码示例:

def find_root(f, a, b, epsilon=1e-6):
    if f(a) * f(b) >= 0:
        raise ValueError("区间 [a, b] 内无根或端点符号相同")
    while b - a > epsilon:
        c = (a + b) / 2
        if f(c) == 0:
            return c
        if f(a) * f(c) < 0:
            b = c
        else:
            a = c
    return (a + b) / 2

三、时间复杂度与复杂度分析

  • 时间复杂度:O(logn),每次将数据规模减半。
  • 空间复杂度:O(1)(迭代实现)或 O(logn)(递归实现,取决于调用栈深度)。

四、优缺点

优点缺点
高效,远快于线性搜索 O(n)要求数据必须有序
实现简单仅适用于可随机访问的数据结构
适用于大规模数据对非单调性问题不适用

五、常见变体与注意事项

  1. 查找第一个/最后一个出现的位置:通过调整条件处理重复元素。
  2. 旋转有序数组查找:结合二分法判断旋转点位置。
  3. 实数域上的精度控制:设置合理的终止条件(如区间长度小于 1e-6)。
  4. 防止整数溢出:使用 mid = left + (right - left) // 2 而非 (left + right) // 2

六、应用场景

  • 数据库索引检索
  • 游戏中的数值猜测(如猜数字)
  • 调试中的“二分注释法”定位 Bug
  • 机器学习中的超参数调优
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值