实现有重复数字的升序数组的二分查找

题目描述:给定一个 元素有序的(升序且有相同元素)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(这里指第一个等于目标值的下标),否则返回 -1。

题目分析:这道题和标准二分的差别是数组元素有重复,且需要找到第一个等于目标值的元素的下标。

提供一版正确的代码:

class Solution {
public:
    /**
     * 如果目标值存在返回下标,否则返回 -1
     * @param nums int整型vector
     * @param target int整型
     * @return int整型
     */
    int search(vector<int>& nums, int target) {
        int start = 0, end = nums.size() - 1;
        if (start > end || nums[start] > target || nums[end] < target) //边界检测
            return -1;
        while (start <= end)
        {
            int mid = (start + end) / 2;
            if (nums[mid] > target)//大于的情况
            {
                end = mid - 1;
            }
            else  if (nums[mid] < target)//小于的情况
                start = mid + 1;
            else// 等于的情况
            {
                if (mid == 0 || nums[mid - 1] != target)//注意先判mid==0,若不成立,再判后面条件,nums[mid-1]才不会 越界
                    return mid;
                else
                    end = mid - 1;
            }
        }
        return  -1;
    }
};

这里还有一版错的代码,但是在某平台上提交也通过了,不知道后台的case是咋跑的。

class Solution {
public:
    /**
     * 如果目标值存在返回下标,否则返回 -1
     * @param nums int整型vector
     * @param target int整型
     * @return int整型
     */
    int search(vector<int>& nums, int target) {
        int start=0,end=nums.size()-1;
        if(start > end || nums[start] > target || nums[end] < target) //边界检测
            return -1;
        while(start<=end)
        {
            int mid=(start+end)/2;
            if(nums[mid]>=target)
            {
                if(mid==0 && nums[mid] > target)//处理只有一个元素且比目标值大的情况
                        return -1;
                else if(mid==0 || nums[mid-1]<target)//这里 nums[mid-1]<target 满足但不能保证 nums[mid]==target,还存在大于的情况,所以认为是错的
                        return mid;
                else
                    end=mid-1;
            }
            else  //nums[mid]<target
                start=mid+1;
        }
        return  -1;
    }
};

 

posted @ 2021-05-20 16:59  justloving  阅读(661)  评论(0编辑  收藏  举报