二分查找

[Algo] 二分查找

注:Algo系列基于左神算法教程,提供C++实现。

1. 经典算法

// 1. 经典二分查找:给定有序序列,查找val,存在返回(任一)索引,否则返回-1
int binarySearch(const vector<int> &v, int val)
{
    if (v.size() == 0) return -1;
    int left = 0, right = v.size() - 1, mid = 0;
    while (left <= right)
    {
        mid = (left + right) / 2;
        // mid = left + (right - left) >> 1
        if (v[mid] == val) return mid;
        else if (v[mid] < val) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

2. 大于等于num的左边界

// 2. 给定有序序列和val,查找不小于val的最左位置,存在返回索引,否则返回-1
int leftNoLessThan(const vector<int> &v, int val)
{
    if (v.size() == 0) return -1;
    int left = 0, right = v.size() - 1, mid = 0, ans = -1;
    while (left <= right) 
    {
        mid = (left + right) / 2;
        if (v[mid] >= val)
        {
            ans = mid;
            right = mid - 1;
        } 
        else
        {
            left = mid + 1;
        }
    }
    return ans;
}

3. 峰值点

// 3. 给定序列(未必有序)(相邻元素不等),找出(任一)峰值点,返回索引
int findPeakIndex(const vector<int> &v)
{
    if (v.size() == 1) return 0;
    if (v[0] > v[1]) return 0;
    if (v[v.size() - 1] > v[v.size() - 2]) return v.size() - 1;
    // [1, v.size() - 2]必存在峰值点
    int left = 1, right = v.size() - 2, mid = 0;
    while (left <= right)
    {
        mid = (left + right) / 2;
        if (v[mid] < v[mid - 1]) right = mid - 1; // [left, mid - 1]必存在峰值点
        else if (v[mid] < v[mid + 1]) left = mid + 1; // [mid + 1, right]必存在峰值点
        else return mid;
    }
    return -1; // 永不执行
}
posted @ 2024-12-02 17:08  yaoguyuan  阅读(3)  评论(0编辑  收藏  举报