34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
样例
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
二分查找
- 本题本质上考察C++STL中lower_bound和upper_bound两个算法的实现
- lower_bound:返回有序数组中大于等于target的第一个数的位置。也即返回目标值在有序数组中第一次出现的位置,本题函数接口与STL该算法接口语义一致。
- upper_bound:返回有序数组中大于target的第一个数的位置。由于本题要求返回目标值最后一次出现的位置,所以本题实现的upper_bound语义与STL不同,本题函数接口语义:返回目标值在有序数组中最后一次出现的位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.empty())
return {-1,-1};
int left=lower_bound(nums,target);
if(left==-1)
return {-1,-1};
int right=upper_bound(nums,target);
return {left,right};
}
//返回有序数组中目标值首次出现的位置
int lower_bound(vector<int>& nums,int target){
int l=0,r=nums.size()-1;
while(l<r){
int mid=l+(r-l)/2;
if(nums[mid]<target)
l=mid+1;
else
r=mid;
}
if(nums[l]==target)
return l;
else
return -1;
}
//返回有序数组中目标值最后一次出现的位置
int upper_bound(vector<int>& nums,int target){
int l=0,r=nums.size()-1;
while(l<r){
int mid=l+(r-l+1)/2;
if(nums[mid]<=target)
l=mid;
else
r=mid-1;
}
if(nums[l]==target)
return l;
else
return -1;
}
};