二分算法框架

  二分算法的前提是排序数组,通过折半查找的方式,将找到目标值的时间复杂度缩小到O(logn)

  最主要的3个问题

  • 查找某元素即返回索引
  • 查找某元素的左边界索引
  • 查找某元素的右边界索引

二分算法框架:

// 查找某元素即返回索引
int binarySearch(int num[], int length, int target){
    if(length < 1)
        return -1;
    int left = 0;
    int right = length - 1;
    // 左右封闭
    while(left <= right){
        int middle = left + ((right - left) >> 1);
        if(num[middle] == target)
            return middle;
        else if(num[middle] > target)
            right = middle - 1;
        else if(num[middle] < target)
            left = middle + 1;
        // 全写else if,不写else,这样更好理解
    }
    // 找不到就直接返回
    return -1;
}


// 查找左边界
int binaryLeftBound(int num[], int length, int target){
    if(length < 1)
        return -1;
    int left = 0;
    int right = length - 1;
    // 左右封闭法(注意也可以左闭右开)
    while(left <= right){
        int middle = left + ((right - left) >> 1);
        if(num[middle] == target)
            // 不着急返回,向左收缩范围
            right = middle - 1;
        else if(num[middle] > target)
            right = middle - 1;
        else if(num[middle] < target)
            left = middle + 1;
    }
    // left可能越界
    if(left >= length || num[left] != target)
        return -1;
    return left;
}

// 查找右边界
int binaryRightBound(int num[], int length, int target){
    if(length < 1)
        return -1;
    int left = 0;
    int right = length - 1;
    // 左右封闭法(注意也可以左闭右开)
    while(left <= right){
        int middle = left + ((right - left) >> 1);

        if(num[middle] == target)
            // 不着急返回,向右收缩范围
            left = middle + 1;
        else if(num[middle] > target)
            right = middle - 1;
        else if(num[middle] < target)
            left = middle + 1;
    }
    if(right < 0 || num[right] != target)
        return -1;
    return right;
}
原文地址:https://www.cnblogs.com/flyingrun/p/13569417.html