7.5小学期基础语法记录:二分搜索

C++ 二分搜索全解笔记

一、二分搜索基本原理

二分搜索(Binary Search)是一种在有序数组中查找目标值的算法,时间复杂度为 O(log n)。其核心思想是:

  • 每次取中点,与目标值比较,缩小搜索区间。

基本流程:

int binarySearch(const vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 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; // not found
}

二、二分搜索常用变种

1. 查找第一个大于等于 target 的位置

int lower_bound(const vector<int>& nums, int target) {
    int left = 0, right = nums.size();
    while(left < right) {
        int mid = left + (right - left) / 2;
        if(nums[mid] < target)
            left = mid + 1;
        else
            right = mid;
    }
    return left;
}

2. 查找第一个大于 target 的位置

int upper_bound(const vector<int>& nums, int target) {
    int left = 0, right = nums.size();
    while(left < right) {
        int mid = left + (right - left) / 2;
        if(nums[mid] <= target)
            left = mid + 1;
        else
            right = mid;
    }
    return left;
}

3. 查找最后一个小于等于 target 的位置(衍生)

int last_leq(const vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1, ans = -1;
    while(left <= right) {
        int mid = left + (right - left) / 2;
        if(nums[mid] <= target) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return ans;
}

三、STL 中的二分工具

引入头文件:

#include <algorithm>

常用函数:

bool binary_search(begin, end, target);         // 存在性判断
auto it = lower_bound(begin, end, target);      // ≥ target
auto it = upper_bound(begin, end, target);      // > target
auto range = equal_range(begin, end, target);   // 等于 target 的区间 [first, second)

四、浮点数二分模板(带精度控制)

double binary(double l, double r) {
    while(r - l > 1e-6) {
        double mid = (l + r) / 2;
        if(check(mid)) r = mid; // check 按照题意算方向
        else l = mid;
    }
    return l;
}

适用于数值逼近类问题,如最大长度/最小时间等连续空间搜索。


五、常见应用场景

应用场景 示例
查找目标值 Leetcode 704. Binary Search
插入位置 Leetcode 35. Search Insert Position
峰值问题 Leetcode 162. Find Peak Element
区间最大值 Leetcode 875. Koko Eating Bananas
时间/长度逼近 浮点二分(剪绳子、油漆工问题)

六、注意事项

  1. 数组必须有序:否则搜索结果错误。
  2. 防止溢出:使用 mid = left + (right - left) / 2
  3. 无限循环风险:需确保 left/right 每轮都变化
  4. 开闭区间区别:如 left < right vs left <= right
  5. 不同返回含义:查找值 vs 查找位置要明确需求

七、总结模板对比

模板 目标 区间写法 停止条件 判断分支
标准搜索 是否存在 [l, r] l <= r == target
lower_bound 第一个 ≥ target [l, r) l < r nums[mid] < target
upper_bound 第一个 > target [l, r) l < r nums[mid] <= target

如需刷题推荐题单,可以继续提供目标方向(基础/难题/浮点/模板题),我可进一步补充。

posted @ 2025-07-06 19:36  十八Eigh18n  阅读(18)  评论(0)    收藏  举报