1.二分

0、参考资料(讲解视频及博客等)

  1. 有序 数据查询
    • 在排序数组/链表中快速定位目标值(如数据库索引查询)
  2. 边界值探测
    • 寻找第一个/最后一个满足条件的元素(如IP地址归属地匹配)
  3. 数值计算优化
    • 求平方根、对数近似值(可结合牛顿迭代法)
  4. 单调函数极值
    • 寻找峰值、谷值(如股票最佳买卖时机)
  5. 答案范围限定问题
    • 在可能解区间内二分逼近最优解(如分蛋糕问题、Koko吃香蕉问题)

二、核心思想/步骤

  1. 核心思想

    • 区间折半:通过不断缩小候选区间,将线性搜索优化为对数级
    • 循环不变量 :保持区间定义的一致性(左闭右闭 [left, right] 或左闭右开 [left, right)
  2. 通用步骤

    a. 初始化左右边界(需覆盖所有可能解)
    b. while(left ≤ right):
    i. 计算 mid = left + (right - left)/2 // 防溢出
    ii. 根据 mid 值与目标关系,选择左半或右半区间
    c. 返回最终索引或边界值

  3. 关键细节

    • 终止条件left > right 时结束循环
    • 边界更新
      • 找精确值:left = mid + 1right = mid - 1
      • 找左边界:right = mid(左闭右开)
      • 找右边界:left = mid + 1

三、代码模板与测试

代码模板 (java 为例)

java 复制代码
// 基础模板:查找目标值(数组升序)
public int binarySearch(int[] nums, int target) {
    int left = 0, right = nums.length  - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) return mid;
        else if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}
// 变种模板:寻找左边界(如LeetCode 34)
public int findLeftBound(int[] nums, int target) {
    int left = 0, right = nums.length;   // 右开区间
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] >= target) right = mid;
        else left = mid + 1;
    }
    return (left < nums.length  && nums[left] == target) ? left : -1;
}

样例

样题:LeetCode 704. 二分查找

复制代码
class Solution {
    public int search(int[] nums, int target) {
        int l = 0,r = nums.length-1;
        while(l<=r){
            int mid = (l+r)>>1;
            if(nums[mid]==target){
                return mid;
            }
            else if(nums[mid]<target){
                l = mid + 1;
            }
            else{
                r = mid - 1;
            }
        }
        return -1;
    }
}

四、优化与同类算法对比

优化方案

  1. 计算优化
    • 用位运算代替除法:mid = (left + right) >> 1(Java无符号右移)
  2. 区间定义统一
    • 始终使用左闭右开区间,减少边界条件判断
  3. 提前终止
    • 在数据量极大时,添加剪枝逻辑,提前结束不可能产生预期解的区间

算法对比/复杂度分析

算法 时间复杂度 空间复杂度 适用场景
二分法 O(log n) O(1) 有序数据或隐式单调函数
线性扫描 O(n) O(1) 无序小规模数据
哈希表 O(1) O(n) 频繁查询但无需范围操作

五、相关题目推荐

  1. 基础应用
  2. 边界变种
  3. 抽象模型
  4. 进阶