算法系列——二分查找(例题)

题目描述(牛客例题)

请实现有重复数字的有序数组的二分查找。
输出在数组中第一个大于等于查找值的位置,如果数组中不存在这样的数,则输出数组长度加一。
示例1
输入

5,4,[1,2,4,4,5]

输出

3

解法一:

class Solution {
public:
    /**
     * 二分查找
     * @param n int整型 数组长度
     * @param v int整型 查找值
     * @param a int整型vector 有序数组
     * @return int整型
     */
    int upper_bound_(int n, int v, vector<int>& a) {
        // write code here
        //数组为空时返回值
        if(n==0)
            return 1;
        //定义区间左值、中值和右值
        int left=0,right=n-1;
        int index;
        //当left和right重合时进行最后一次比较
        while(left<=right){
            index=(left+right)/2;
            if(a[index]>=v){//查找值小于等于中值时
                if(index==0||a[index-1]<v)//考虑到第一个值就是所求值的情况,防止index-1数组越界(短路运算)
                    return index+1;
                else
                    right=index-1;
            }else{//查找值大于中值时
                left=index+1;
            }
        }
        //如果查找到目标值在循环体中返回,未查找到在此处返回数组长度加1
        return n+1;
    }
};

解法二:

class Solution {
public:
    /**
     * 二分查找
     * @param n int整型 数组长度
     * @param v int整型 查找值
     * @param a int整型vector 有序数组
     * @return int整型
     */
    int upper_bound_(int n, int v, vector<int>& a) {
        // write code here
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (a[mid] < v) {
                left = mid + 1;
            } else if (a[mid] > v) {
                right = mid - 1;
            } else if (a[mid] == v) {
                // 别返回,锁定左侧边界
                right = mid - 1;
            }
        }
        // 最后要检查 left 越界的情况
        if (left >= n || a[left] < v)
            return n+1;
        return left+1;
    }
};

你可能感兴趣的:(算法分析与设计,算法,二分法,数据结构)