算法入门——二分法

二分法真的很容易出错!!!在用dp学习之后总结了一下二分法

二分查找关键总结


一、核心思想
  • 分治策略:每次将搜索范围缩小一半,适用于有序数组

  • 时间复杂度O(log n),比线性查找高效得多。


二、关键点
  1. 前提条件

    • 有序性:数组必须有序(升序或降序),否则需先排序(但排序成本 O(n log n))。

    • 静态性:适合静态数据或低频更新的数据(高频更新建议用哈希表或树结构)。

  2. 两种边界问题

    • 左边界:第一个等于目标的位置(或第一个大于等于目标的位置)。

    • 右边界:最后一个等于目标的位置(或最后一个小于等于目标的位置)。

  3. 循环终止条件

    • 通常用 while (left < right),退出时 left == right 即为答案。

    • 最终需验证 a[left] 是否等于目标值(处理不存在的情况)。

  4. 中间值计算

    • 标准写法mid = left + (right - left) / 2(防溢出)。

    • 右边界特例mid = left + (right - left + 1) / 2(避免死循环)。


三、难点
  1. 边界条件处理

    • 左边界场景

      • mid 不 +1,区间收缩方向为 right = mid

      • 例如:找第一个 >=x 的位置。

    • 右边界场景

      • mid 必须 +1,区间收缩方向为 left = mid

      • 例如:找最后一个 <=x 的位置。

  2. 死循环的根源

    • 当只剩两个元素时,整数除法的向下取整特性可能导致区间无法缩小。

    • 解决方案:右边界场景需对 mid 计算 +1。

  3. 重复元素的处理

    • 需要分别找到左边界和右边界(如 LeetCode 34 题)。


四、易错点
  1. 直接比较索引与值

    • 错误写法if (mid == x)(应比较 a[mid] 和 x)。

  2. 未验证结果有效性

    • 循环结束后未检查 a[left] 是否等于目标值,导致错误返回。

  3. 混淆排序与查找

    • 二分查找本身不排序,若数组无序需先排序(但可能不符合实际需求)。

  4. 错误的条件分支

    • 例如:左边界查找中误用 left = mid + 1 导致跳过目标。


五、模板代码对比
场景 左边界查找 右边界查找
mid计算 mid = left + (right-left)/2 mid = left + (right-left+1)/2
区间更新 right = mid left = mid
终止条件 while (left < right) while (left < right)

六、经典应用场景
  1. 精确查找:有序数组中找目标值。

  2. 近似查找:求平方根、寻找插入位置(LeetCode 35)。

  3. 边界问题:第一个/最后一个等于目标的位置(LeetCode 34)。

  4. 旋转数组:搜索旋转排序数组(LeetCode 33)。


七、调试技巧
  1. 打印中间变量:在循环中输出 leftrightmid 的值。

  2. 小数据测试:手动模拟只剩 2 个元素的场景。

  3. 极端用例:全相同元素、目标值不存在、目标值在首尾位置。


八、总结口诀
  1. 左边界不 +1,右边界必 +1

  2. 循环条件 < 号,退出记得判有效

  3. 先左后右分开查,重复元素也不怕

你可能感兴趣的:(算法,数据结构,c++,蓝桥杯)