给定一个按照升序排列的整数数组 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]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109
基本思路:有序,二分查找,先找到target,然后向两边扩展
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0||target<nums[0]||target>nums[nums.size()-1])
return {-1,-1};
int l=0,r=nums.size()-1;
while(l<=r){
int mid=(l+r)>>1;
if(nums[mid]>target){
r=mid-1;
}
else if(nums[mid]<target){
l=mid+1;
}
else{
int left,right;
left=right=mid;
while(left>=l&&left>=0){
if(nums[left]!=target)
break;
left--;
}
while(left<=right&&right<nums.size()){
if(nums[right]!=target)
break;
right++;
}
return {left+1,right-1};
}
}
return {-1,-1};
}
基本思路:二分法查找
- 找到目标元素的第一个,nums[mid]>=target
- 找到目标元素的最后一个的右边位置,nums[mid]>target
int binarySearch(vector<int> &nums,int target,bool lower){
int left=0,right=nums.size()-1;
int ans=nums.size(); //防止在target正好是最后一个元素。
while(left<=right){
int mid=(left+right)>>1;
if(nums[mid]>target||(lower&&nums[mid]>=target)){
right=mid-1;
ans=mid;
}
else{
left=mid+1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0||target<nums[0]||target>nums[nums.size()-1])
return {-1,-1};
int leftIdx=binarySearch(nums,target,true);
int rightIdx=binarySearch(nums,target,false)-1;
//cout<<leftIdx<<" "<<rightIdx<<endl;
if(leftIdx<=rightIdx&&rightIdx<nums.size()&&nums[leftIdx]==target&&nums[rightIdx]==target){
return {leftIdx,rightIdx};
}
return {-1,-1};
}