一、题目描述
二、解题思路
整体思路:
由于问题具有“二段性”(目标值可以把向量划分成不同的两段),所以可以采用二分法来查找左边界和右边界。
具体思路:
(1)首先,需要进行边界处理,如果向量为空,则直接返回{-1,-1};
以示例一为例子,nums={5,7,7,8,8,10},target=8
(2)查找左端点(已标红)
二段性:左端点及其右边的数均大于等于target,左端点左边的数均小于target
//查找左边界
int begin;
int left=0,right=nums.size()-1;
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<target) left=mid+1;
else if(nums[mid]>=target) right=mid;
}
begin=left;
(3)查找右端点(已标绿):
二段性:右端点及其左边的数均小于等于target,右端点右边的数均大于target
//查找右边界
int end;
right=nums.size()-1;
while(left<right){
int mid=left+(right-left+1)/2;
if(nums[mid]<=target) left=mid;
else if(nums[mid]>target) right=mid-1;
}
end=right;
如果没找到就返回{-1,-1},如果找到了就返回{begin,end};
三、代码实现
时间复杂度:T(n)=O(logn)
空间复杂度:S(n)=O(1)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
//边界处理
if(nums.empty()) return{-1,-1};
//查找左边界
int begin;
int left=0,right=nums.size()-1;
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<target) left=mid+1;
else if(nums[mid]>=target) right=mid;
}
begin=left;
//查找右边界
int end;
right=nums.size()-1;
while(left<right){
int mid=left+(right-left+1)/2;
if(nums[mid]<=target) left=mid;
else if(nums[mid]>target) right=mid-1;
}
end=right;
if(nums[left]==target) return {begin,end};
else return {-1,-1};
}
};