在排序数组中查找元素的第一个和最后一个位置(二分查找)

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

 

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

 

class Solution {
public:
    int getLeftBorder(vector<int>& nums, int target){
        int left = 0;
        int right = nums.size()-1;
        //为什么初始化为-2?,如果为-1,例如数组{1},target为1,其左右边界为{-1,1},而程序会直接返回{-1,-1},而不是返回{-1+1,1-1},即{0,0}
        int leftBorder = -2;
        while(left<=right){
            int mid = left + (right-left)/2;
            if(nums[mid]<target){
                left = mid+1;
            }else{//当nums[mid]==target时,也更新right,这样才能找到左边界
                right = mid-1;
                leftBorder = right;
            }
        }
        return leftBorder;
    }
    int getRightBorder(vector<int>& nums, int target){
        int left = 0;
        int right = nums.size()-1;
        int rightBorder = -2;
        while(left<=right){
            int mid = left + (right-left)/2;
            if(nums[mid]>target){
                right = mid-1;
            }else{//当nums[mid]==target时,也更新left,这样才能找到右边界
                left = mid+1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftBorder = getLeftBorder(nums,target);
        int rightBorder = getRightBorder(nums,target);
         //该数值不存在于数组中,但存在于数组的右边或左边之外
         //例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}
        if(leftBorder==-2||rightBorder==-2) return vector<int>{-1,-1};
        //该数值的右边界与左边界差值大于1,就返回其边界值
        if(rightBorder-leftBorder>1) return vector<int>{leftBorder+1,rightBorder-1}; 
        //该数值不存在于数组中,但存在于数组的范围之内
        //例如数组{3,6,7},target为5,此时应该返回{-1, -1}
        return vector<int>{-1,-1};
    }
};

 

posted on 2025-01-02 10:17  _月生  阅读(19)  评论(0)    收藏  举报